下面这段代码理论上不是应该产生死锁吗,放到winform中完美死锁,但是放到ashx中就没有死锁,这是什么情况啊
public class Req : IHttpHandler {
public void ProcessRequest(HttpContext context) {
GetResult();
context.Response.ContentType = "text/plain";
context.Response.Write("hello world");
}
private string GetResult() {
return AAA().Result;
}
async Task<string> AAA() {
return await BBB();
}
async Task<string> BBB() {
await Task.Delay(100);
return "为什么不会死锁呢";
}
public bool IsReusable {
get {
return false;
}
}
}
放在aspx页面中试下,死锁的原因是UI主线程跟异步线程之间的互持等待,这个也仅限于core之前的asp.net,winform这些,但ashx应该不同于aspx有ui主线程,没有synchornizedContext(猜测),具体的需要翻源码
ashx也会死锁,我之前一个老项目就会死锁,每次本地调试都会,但是老项目业务太复杂了不方便调试,所以我就照着老项目的样子搞了一个简单的例子,就是我贴的代码了,然而奇怪的是它不会死锁了
突然想起来例子和老项目还是有点不同的地方的,老项目通过HttpModule实现URL重写,并不是直接请求ashx文件,可能问题出在了这里,有可能是ashx本身不会死锁,但是URL重写后死锁了,我在研究研究
达到一定的并发量才会发生死锁,详见 一码阻塞,万码等待:ASP.NET Core 同步方法调用异步方法“死锁”的真相
我有个类似这个结构的旧项目,本地调试每次都死锁,而且我这个是很久之前的asp.net不是现在的asp.net core,旧项目死锁的问题我在网上找到了解决方式加了.ConfigureAwait(false)后正常了,原因是asp.net中的上下文竞争导致的相互阻塞,于是我就试着自己模拟死锁加深理解,但是自己写的小例子却无法触发死锁,完全不知道是怎么回事了 _
我的理解是,iis会把请求放到一个队列里面,你来个请求我给你封装一个对象,放入管道中,不管处理完没有,继续接受下一个请求了,每次请求都是对于ash.x都是独立的。而且iis里有线程池,如果请求数量没有超过这个线程池的线程数量极限,是不会阻塞的。如果你想发生死锁,可以找一个互斥资源,让两个请求几乎同时去请求这个资源,并且互相都不释放这个资源,就可能会死锁。
你循环并发请求,看看
– 我不舔了 3年前@我不舔了: 还是不行啊
····
<script>
aaa();
setTimeout(function () {
console.log("aaaaaaaaa");
aaa();
}, 100);
····
– WmW 3年前