同时等待多个具有独立延续的 WCF 异步调用

Posted

技术标签:

【中文标题】同时等待多个具有独立延续的 WCF 异步调用【英文标题】:Concurrently awaiting multiple WCF asynchronous calls with independent continuations 【发布时间】:2020-01-15 05:18:31 【问题描述】:

我有一个场景,我需要调用多个 WCF 异步调用,这些调用可以彼此独立进行,每个调用都有自己的更新 UI 的延续。

假设我有这样的功能:

private Task<bool> ExecuteSomeWorkAsync(int delay)
 
     int _delay = delay;
     var t = Task<bool>.Factory.StartNew(
         () =>
         
             Thread.Sleep(_delay);

             return true;
         );

     return t;
 

如果我创建了一个本地 WPF 应用程序,该应用程序进行了多次调用,每个调用都可能在时间上有所不同以返回结果,它会按预期工作。 在示例中,第二个任务在第一个任务之前完成,并且绑定到第二个属性的 UI 元素在第一个任务之前更新。

 TaskScheduler uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
                    await Task.WhenAll(
                        ExecuteSomeWorkAsync(2000).ContinueWith(task1 =>  SomePropertyBoundToUIElement1 = task1.Result; , uiScheduler),
                        ExecuteSomeWorkAsync(1000).ContinueWith(task2 =>  SomePropertyBoundToUIElement2 = task2.Result; , uiScheduler)
                        );

但是,如果我尝试在通过客户端代理调用 ExecuteSomeWorkAsync 的 WCF 中实现此功能,则 UI 仅在最慢之后才更新 任务完成。

那么,有没有办法在 WCF 中完成这项工作?

【问题讨论】:

ExecuteSomeWorkAsync 是否是客户端代理方法无关紧要;客户端的 UI 调度也一样。肯定有其他问题。 【参考方案1】:

要回答我自己的问题,有一种方法可以使示例在 WCF 中运行。 解决方案是指定适当的 ConcurrencyMode 选项。

通过使用此服务行为装饰 WCF 服务,我获得了我所追求的并行性。

 [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple)]

显然 WCF 默认为 Single ConcurrencyMode,因此服务按顺序解析请求。

【讨论】:

以上是关于同时等待多个具有独立延续的 WCF 异步调用的主要内容,如果未能解决你的问题,请参考以下文章

System.OutOfMemoryException 对 WCF 服务的多个异步调用

异步调用 WCF 服务并在新任务中等待它

委派同步 WCF 调用以启动异步进程

如何异步调用我的 WCF 服务?

如何在异步函数中处理多个等待

[概念] 同步 异步 阻塞 非阻塞