1

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

我运行 Perfmon,观察系统上的线程数,它在 28-30 之间。我的客户需要几个小时才能完成拨打的大量电话。是的,小时。远程服务由一家大公司提供支持,他们有很多服务器来接收我的 WCF 调用,所以我可以向它们发送的调用越多越好。

我认为事情实际上仍在同步发生,即使进行 WCF 调用的方法用“async”装饰,因为代理方法不能有“await”。真的吗?

我的代码如下所示:

   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

responseInfo 不可等待,因为 WCF 调用具有 ref 和 out 参数。

我在想加快速度的方法不是将 async/await 放在这个方法中,而是创建一个包装器方法,我可以在其中使事情 await/async,但我不是最聪明/最安全的工作方式。

什么是获得更多对服务的出站调用的聪明方法(扩展 IO 完成线程池,欺骗调用在后台运行,以便 Task.WhenAll 可以更快地完成)?

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

4

1 回答 1

4

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

ServicePointManager.DefaultConnectionLimit = 100;

默认情况下,它只允许 2 个同时连接到同一服务器。
3) 确保在调用完成后处理代理对象,以免占用资源。

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

你也可以用一个你知道不会有任何瓶颈的非常简单的方法来代替你的真实调用,看看问题出在客户端还是服务器上。

于 2012-12-04T16:48:57.717 回答