C# 为什么我的异步任务要等待对方完成?
当我单击我的按钮时,我希望我的标签文本在C# 为什么我的异步任务要等待对方完成?,c#,.net,wpf,multithreading,async-await,C#,.net,Wpf,Multithreading,Async Await,当我单击我的按钮时,我希望我的标签文本在5秒内设置好(因为我的WCF方法调用只休眠了5秒钟)。嗯,这需要10秒。现在,当我只进行三次服务呼叫而不是四次服务呼叫时,标签将在5秒内设置好 当我在性能监视器中观察所有四个呼叫时的呼叫计数时,我只看到3个呼叫进入,然后在前三个呼叫结束后,其他1个呼叫进入。查看这篇MSKB文章: 总而言之,您的WCF服务的默认IOCP线程池似乎处于饥饿状态(很难说为什么;请查看ThreadPool.GetMinThreads和ThreadPool.GetAvailable
5秒内设置好(因为我的WCF方法调用只休眠了5秒钟)。嗯,这需要10秒。现在,当我只进行三次服务呼叫而不是四次服务呼叫时,标签将在5秒内设置好
当我在性能监视器中观察所有四个呼叫时的呼叫计数时,我只看到3个呼叫进入,然后在前三个呼叫结束后,其他1个呼叫进入。查看这篇MSKB文章:
总而言之,您的WCF服务的默认IOCP线程池似乎处于饥饿状态(很难说为什么;请查看ThreadPool.GetMinThreads
和ThreadPool.GetAvailableThreads
)。因此,最有可能的情况是,当您在为\u wcfProxy.a()
服务时使用thread.Sleep
阻止WCF线程时,没有其他线程可为\u wcfProxy.B()
服务,因此B
请求排队,直到a
完成
尝试实现WorkerThreadPoolSynchronizer
和WorkerThreadPoolBehaviorAttribute
,将[WorkerThreadPoolBehavior]
应用于和A
和B
,看看这是否解决了问题。是否针对同一台机器上本地运行的WCF服务实例进行测试?另外,如果您将_wcfProxy.A/B调用替换为just Task.Delay(5000),那么它是否能像预期的那样工作?@noserio我知道在您提交了答案后我会回答这个问题,但如果这意味着什么……我正在本地计算机上运行它,但是如果我从不同的服务器上点击它,结果是一样的。如果我替换了Wcf
调用,那么它就会像预期的那样工作。这就是原因,但是我对从Wpf应用程序向新线程发送Wcf调用如何改变事情有点困惑。Wpf应用程序中的线程与Wcf服务上的线程相关?忽略我的最后一条评论。将其发送到新线程并不能解决此问题。但是,在异步wcf调用后放置.ConfigureAwait(false)
可以解决问题,但这不是一个单独的问题。@James您如何/在何处将ConfigureAwait
添加到各个调用中?不能只执行vart1=\u wcfProxy.A().ConfigureAwat()
,因为它不会返回任务。或者,如果您执行wait _wcfProxy.A().ConfigureAwat()
,则它不再是并行任务流。很抱歉造成混淆。你说得对。不久前我已经测试过了,认为.ConfigureAwait()
让我成功了。我仍然认为Wpf没有发送第四个请求。我不相信这是服务器端的问题,尽管我可能是错的。我相信你关于线程问题的看法是正确的,但是我在过去24小时内进行了大量调试,似乎无法准确找出原因。我已经把细节转移到一个新的问题上,这个问题在这里更具体
private async void StartTasks_Click(object sender, RoutedEventArgs e)
{
await Task.WhenAll(GetSomeData());
lblResult.Text = "Got data?";
}
private async Task GetSomeData()
{
System.Net.ServicePointManager.DefaultConnectionLimit = 16;
ServiceClient _proxy = new ServiceClient();
//*** the wcf proxy service methods just sleep for 5 seconds.
var t1 = _wcfProxy.A();
var t2 = _wcfProxy.A();
var t3 = _wcfProxy.A();
var t4 = _wcfProxy.A();
await Task.WhenAll(t1,t2,t3,t4);
}