.NET 4.5增加WCF客户端调用异步?

时间:2012-12-03 18:56:38

标签: multithreading wcf async-await

我有一个.NET 4.5 WCF客户端应用程序,它使用async / await模式来进行大量调用。我的开发机器是带有8GB RAM的双进程(在亚马逊AWS上将生产5个CPU和8GB RAM)。我的代码调用的远程WCF服务在我需要的Web方法上使用out和ref参数。我的代码每次都实例化一个代理客户端,将任何结果写入公共ConcurrentDictionary,然后返回null。

我跑了Perfmon,看着系统上的线程计数,它在28-30之间。我的客户端需要几个小时才能完成所做的调用。是的,几小时。远程服务由一家大公司支持,他们有许多服务器来接收我的WCF呼叫,因此我可以向他们拨打的电话越多越好。

我认为事情实际上仍然是同步发生的,即使使用“async”进行WCF调用的方法也是如此,因为代理方法不能“等待”。真的吗?

我的代码如下所示:

   async private void CallMe()
    {
    Console.WriteLine( DateTime.Now );
    var workTasks = this.AnotherConcurrentDict.Select( oneB => GetData( etcetcetc ).Cast<Task>().ToList();
    await Task.WhenAll( workTasks );
    }


    private async Task<WorkingBits> GetData(etcetcetc)
    {
    var commClient = new RemoteClient();
    var cpResponse = new GetPackage();
    var responseInfo = commClient.GetData( name, password , ref (cpResponse.aproperty), filterid , out cpResponse.Identifiers);
    foreach (var onething in cpResponse.Identifiers)
    { 
        // add to the ConcurrentDictionary
    }
    return null; // I already wrote to the ConcurrentDictionary so no need to return anything

由于WCF调用具有ref和out参数,因此无法响应responseInfo。

我认为加快这一步的方法不是在这个方法中放入async / await,而是创建一个包装器方法,我可以让事情等待/异步,但我不是那种最聪明/最安全的方式解决它。

什么是获得更多服务出站调用的智能方法(扩展IO完成线程池,将调用设置为在后台运行,以便Task.WhenAll可以更快地完成)?

感谢所有想法/样本/指针。我在某个地方遇到了瓶颈。

1 个答案:

答案 0 :(得分:3)

1)确保你真的是异步调用它,而不是仅仅阻止调用。代码示例在这里会有所帮助。
2)您可能需要这样做:

ServicePointManager.DefaultConnectionLimit = 100;

默认情况下,它只允许同时连接到同一台服务器 3)确保在呼叫完成后丢弃代理对象,这样就不会占用资源。

如果您正在异步执行操作,则线程池大小不应成为瓶颈。为了更好地了解您遇到的问题类型,您可以使用Interlocked.IncrementInterlocked.Decrement来跟踪待处理呼叫的数量,并查看它是否在某个地方受到限制。

您也可以通过调用一个非常简单的方法来替换您的真实呼叫,该方法您知道不会有任何瓶颈,以查看问题是在客户端还是服务器中。