代码之家  ›  专栏  ›  技术社区  ›  Mikael Svenson

在进行异步wcf调用时,首选哪种方法?

  •  7
  • Mikael Svenson  · 技术社区  · 16 年前

    当异步调用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> 类我们有一个简单的第三种方法,即在任务中包装同步操作。

    三。

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

    它们都能让你在等待结果的同时执行其他代码,但我认为 任务<t> 更好地控制在检索结果之前或之后执行的操作。

    使用一个比另一个有什么优点或缺点吗?或者一种方法更可取的情况?

    2 回复  |  直到 15 年前
        1
  •  5
  •   Aaronaught    16 年前

    我愿意 使用最终版本,因为它将在工作线程而不是I/O线程上运行操作。如果您在asp.net中执行此操作,则情况尤其糟糕,因为在asp.net中需要工作线程来服务请求。更不用说,你还在主线程上阻塞等待任务完成,当你检查它的时候 Result ,所以严格来说你是在浪费 工作线程,或者一个工作线程和ui。

    这个 BeginXYZ XyzAsync wcf客户机的方法工作原理基本相同——您应该根据您想要支持的用例(分别是apc或事件驱动的)选择适当的版本。例如, BeginXyz 版本在asp.net(或mvc)异步页面中更容易使用(可能是反直觉的),而 木薯 在windows窗体中更容易使用版本。

        2
  •  2
  •   Josh    16 年前

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

    但一般来说,我更喜欢选项1,因为它使使用匿名方法处理结果变得非常容易。

    var client = new WcfClient();
    client.BeginDoSearch("input", ar => {
    
        var result = client.EndDoSearch(ar);
        // blah blah
    
    }, null);