在进行异步WCF调用时,首选哪种方式?

时间:2010-04-10 20:20:09

标签: c# .net wcf asynchronous .net-4.0

当异步调用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 个答案:

答案 0 :(得分:5)

使用最终版本,因为它将在工作线程而不是I / O线程上运行操作。如果您在ASP.NET中执行此操作尤其糟糕,其中需要工作线程来处理请求。更不用说,当你检查Result时,你仍然在主线程上阻塞等待任务完成,所以从技术上来说你浪费了两个工作线程,或者一个工人和用户界面。

WCF客户端的BeginXYZXyzAsync方法基本上以相同的方式工作 - 您应该根据要支持的用例(分别是APC或事件驱动)选择适当的版本。例如,BeginXyz版本(可能违反直觉)在ASP.NET(或MVC)异步页面中更容易使用,而XyzAsync版本在Windows窗体中更容易使用。 / p>

答案 1 :(得分:2)

你的第一个例子有问题。当你调用EndDoSearch时,你当然应该创建一个新的WcfClient实例。您应该将原始实例保留在字段中,或者将其作为状态参数传递。

但总的来说,我更喜欢选项#1,因为它可以很容易地使用匿名方法来处理结果。

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

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

}, null);