Какой путь предпочтен при выполнении асинхронных вызовов WCF?

Когда вызов сервиса WCF, асинхронного там, кажется, два способа, которыми он может быть сделан.

1.

WcfClient _client = new WcfClient();    
public void One()
{
    _client.BegindoSearch("input", ResultOne, null);
}

private void ResultOne(IAsyncResult ar)
{
    string data = _client.EnddoSearch(ar);
}

2.

public void Two()
{
    WcfClient client = new WcfClient();
    client.doSearchCompleted += TwoCompleted;
    client.doSearchAsync("input");
}

void TwoCompleted(object sender, doSearchCompletedEventArgs e)
{
    string data = e.Result;
}

И с новым Task<T> класс у нас есть легкий третий путь путем обертывания синхронной операции в задачу.

3.

public void Three()
{
    WcfClient client = new WcfClient();
    var task = Task<string>.Factory.StartNew(() => client.doSearch("input"));
    string data = task.Result;
}

Они все дают Вам способность выполнить другой код, в то время как Вы ожидаете результата, но я думаю Task<T> дает лучший контроль на том, что Вы выполняете, прежде или после того, как результат получен.

Есть ли какие-либо преимущества или недостатки к использованию того по другому? Или сценарии, где один способ сделать его более предпочтителен?

7
задан Mikael Svenson 10 April 2010 в 21:18
поделиться

2 ответа

Я бы не использовал финальную версию, потому что она будет выполнять операцию на рабочем потоке вместо потока ввода-вывода. Это особенно плохо, если вы делаете это внутри ASP.NET, где рабочие потоки нужны для обслуживания запросов. Не говоря уже о том, что при проверке Result вы все еще блокируете основной поток, ожидая завершения задачи, так что технически вы тратите два рабочих потока или один рабочий и UI.

Методы BeginXYZ и XyzAsync для WCF-клиентов работают по сути одинаково - вы должны выбрать подходящую версию на основе сценария использования, который вы хотите поддерживать (либо APC, либо событийно-управляемый, соответственно). Например, версию BeginXyz (возможно, нелогично) будет проще использовать в асинхронной странице ASP.NET (или MVC), тогда как версию XyzAsync будет проще использовать в Windows Form.

5
ответ дан 7 December 2019 в 07:42
поделиться

В вашем первом примере возникла проблема. Вы, безусловно, должны не создавать новый экземпляр WcfClient при вызове EndDoSearch. Вы должны либо оставить исходный экземпляр в поле, либо передать его в качестве параметра состояния.

Но в целом я предпочитаю вариант №1, потому что он позволяет очень легко использовать анонимный метод для обработки результата.

var client = new WcfClient();
client.BeginDoSearch("input", ar => {

    var result = client.EndDoSearch(ar);
    // blah blah

}, null);
2
ответ дан 7 December 2019 в 07:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: