【问题标题】:WCF ChannelFactory asynchronous callWCF ChannelFactory 异步调用
【发布时间】:2013-06-23 18:00:13
【问题描述】:

我正在使用 WCF 和 TPL 异步库 我需要的是能够请求多个 WCF 方法并等到所有方法都完成,到目前为止,我发现在 .NET 4.5 中有一个非常方便的方法 Task.Factory.ContinueWhenAll 可以用来等到所有通话结束

我发现了以下方式以异步方式请求 WCF 调用
选项 1. 通过使用“添加引用”对话框生成的代理和选项“生成基于任务的操作”-> [例如此处][1] - 在我的情况下不是一个选项,因为我们使用的是原始 ChannelFactory
选项 2. 通过将同步调用包装在任务中,例如

    ChannelFactory<IService1> factory = new ChannelFactory<IService1>("BasicHttpBinding_IService1");  

        Task<string> t1 = Task<string>.Factory.StartNew(() => { return factory.CreateChannel().GetData(2); });
        Task<string> t2 = Task<string>.Factory.StartNew(() => { return factory.CreateChannel().GetData(5); });

        Task.Factory.ContinueWhenAll(new[] { t1, t2 }, t =>
        {
            foreach (var task in t)
            {
                //get result here
            }
        });

选项 3. 通过创建客户端异步版本的合约接口,例如

[ServiceContract(Namespace = "X", Name = "TheContract")]//Server side contract
public interface IService1
{
    [OperationContract]
    string GetData(int value);
}

[ServiceContract(Namespace = "X", Name = "TheContract")]//client side contract
public interface IService1Async
{
    [OperationContract]
    string GetData(int value);

    [OperationContract]
    Task<string> GetDataAsync(int value);
}

有了这个我可以异步调用方法,例如

 ChannelFactory<IService1Async> factory = new ChannelFactory<IService1Async>("BasicHttpBinding_IService2");

        var t1 = factory.CreateChannel().GetDataAsync(2);
        var t2 = factory.CreateChannel().GetDataAsync(5);

        Task.Factory.ContinueWhenAll(new[] { t1, t2 }, (Task<string>[] t) =>
            {
                foreach (var task in t)
                {
                    //get result here
                }
            });

所以问题如下,与选项2相比,选项3有什么优势,在选项2中调用WCF方法是否正确?方案2与方案3相比有一个优势,即无需创建客户端合约接口。

【问题讨论】:

  • 如果您使用的是 .Net 4.5,为什么不使用 async-await
  • 也许我做错了什么,但是当我尝试使用异步执行两个调用时,例如var t1 = await factory.CreateChannel().GetDataAsync(2); var t2 = await factory.CreateChannel().GetDataAsync(5);并且每个调用都是异步的,但它们不是同时执行的->第二个请求在第一个请求完成后开始。
  • 嗯,那是因为await 不会改变执行顺序。您需要调用第一个方法并存储其Task,调用第二个方法并存储其Task,然后再存储await
  • 我知道必须有一种方法可以通过我之前提到的异步来缓解这个问题,谢谢。但主要问题仍然悬而未决,哪个选项更好?

标签: wcf asynchronous task-parallel-library task channelfactory


【解决方案1】:

在选项#2 中,每次调用GetData() 都会在方法执行的整个过程中阻塞一个线程。在选项#3 中,当GetDataAsync() 操作正在进行时,没有线程被它阻塞。

这意味着选项 #3 更有效,如果效率对您很重要,您应该使用该方法的 -Async 版本。

【讨论】:

  • 嗨 svick,我有一个类似的问题,想知道你是否可以分享 async 等价物。我从同步方法调用,但想异步调用多个 WCF 服务。所以:stackoverflow.com/q/57572902/919426。如果您回答此问题的示例和解决我的 SO 问题的替代方案,我将奖励您赏金:)
猜你喜欢
  • 2014-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-06
  • 2012-10-03
  • 1970-01-01
  • 2012-10-25
  • 2011-08-24
相关资源
最近更新 更多