pm1*_*100 19 c# task-parallel-library
我喜欢新的System.Net.Http.HttpClient类.它有一个很好的简单API,它不会抛出正常的错误.但它只是异步.
我需要代码(深入服务器内)
foo();
bar();
// compute stuff
var x = GetThingFromOtherServerViaHttp();
// compute more stuff
wiz(x);
Run Code Online (Sandbox Code Playgroud)
经典的顺序同步代码.我看到了几个类似的问题,但实际上从未真正说过"做这个".我在看
client.PostAsync.Wait()
Run Code Online (Sandbox Code Playgroud)
世界尖叫'不要这样做'.怎么样:
client.PostAsync.Result()
Run Code Online (Sandbox Code Playgroud)
这不只是伪装等待?
最后,我最终传入一个处理结果的lambda回调,然后唤醒显式等待EventWaitHandle的调用线程.很多管道.有没有更简单的东西或者我只是回到使用旧的http客户端
编辑:进一步阅读后,我怀疑这段代码与Wait和Result有相同的问题,它只是一个更长的死锁
编辑:我有MS PM最近向我确认有一个任务'可能需要> X ms(我忘了X)的任何API必须是异步',许多PM将此解释为'仅异步'(不清楚这是什么旨在).因此Document DB api只是异步.
来自http://blogs.msdn.com/b/pfxteam/archive/2012/04/13/10293638.aspx:
return Task.Run(() => Client.PostAsync()).Result;
Run Code Online (Sandbox Code Playgroud)
@Noseratio - 当然我担心死锁:-)
如果你在具有同步上下文的线程上,你只会担心死锁.
这通常是UI应用程序的主线程(客户端),或随机ASP.NET线程处理HTTP请求(服务器端).在任何一种情况下,你真的不应该阻止它.
接受的答案可能有助于缓解死锁,但是这样的阻塞仍然会影响UI应用程序的最终用户体验(UI会被冻结),或服务器端应用程序的可伸缩性(线程浪费了阻塞,而它可能是提供另一个请求).只是不要阻止并一直使用async/await.
您提到"服务器内部深处",但没有提供有关服务器端应用程序的详细信息.大多数现代服务器端框架都有很好的管道async/await,所以它不应该是一个问题.
更新以解决评论:
我仍然不喜欢在不同地方编写的相同代码会死锁的事实.我希望在一个容易出现死锁的环境中等待调用
这不是特别的问题,async/await但是当它与阻塞代码一起使用时,通常是同步上下文概念的问题.简而言之,这就是僵局:
private void Form1_Load(object sender, EventArgs e)
{
var mre = new System.Threading.ManualResetEvent(initialState: false);
System.Threading.SynchronizationContext.Current.Post(_ =>
mre.Set(), null);
mre.WaitOne();
MessageBox.Show("We never get here");
}
Run Code Online (Sandbox Code Playgroud)
从理论上讲,有可能尝试SynchronizationContext.Post通过检查来减轻内部潜在的死锁Thread.ThreadState == System.Threading.ThreadState.WaitSleepJoin.然而,这不是100%可靠的解决方案.