Какой способ предпочтительнее при выполнении асинхронных вызовов WCF? - PullRequest
7 голосов
/ 11 апреля 2010

При вызове службы 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> дает лучший контроль над тем, что вы выполняете до или после получения результата.

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

Ответы [ 2 ]

5 голосов
/ 11 апреля 2010

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

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

2 голосов
/ 11 апреля 2010

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

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

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

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

}, null);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...