首页 新闻 会员 周边

asp.net的ashx中这样用async/await 为什么不死锁了啊

0
悬赏园豆:20 [已解决问题] 解决于 2022-02-15 09:11

下面这段代码理论上不是应该产生死锁吗,放到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;
            }
        }
    }
WmW的主页 WmW | 菜鸟二级 | 园豆:424
提问于:2021-12-02 16:51

你循环并发请求,看看

我不舔了 2年前

@我不舔了: 还是不行啊
····
<script>
aaa();
setTimeout(function () {
console.log("aaaaaaaaa");
aaa();
}, 100);

function aaa() {
    for (var i = 0; i < 99; i++) {
        $.ajax({
            url: "Req.ashx",
            dataType: "text",
            success: function (re) {
                console.log(re);
            },
        });
    }
}

····

WmW 2年前
< >
分享
最佳答案
0

放在aspx页面中试下,死锁的原因是UI主线程跟异步线程之间的互持等待,这个也仅限于core之前的asp.net,winform这些,但ashx应该不同于aspx有ui主线程,没有synchornizedContext(猜测),具体的需要翻源码

收获园豆:20
some-body | 菜鸟二级 |园豆:242 | 2022-01-06 09:48

ashx也会死锁,我之前一个老项目就会死锁,每次本地调试都会,但是老项目业务太复杂了不方便调试,所以我就照着老项目的样子搞了一个简单的例子,就是我贴的代码了,然而奇怪的是它不会死锁了

WmW | 园豆:424 (菜鸟二级) | 2022-01-06 11:40

突然想起来例子和老项目还是有点不同的地方的,老项目通过HttpModule实现URL重写,并不是直接请求ashx文件,可能问题出在了这里,有可能是ashx本身不会死锁,但是URL重写后死锁了,我在研究研究

WmW | 园豆:424 (菜鸟二级) | 2022-01-06 11:46
其他回答(2)
0
dudu | 园豆:30994 (高人七级) | 2021-12-02 17:20

我有个类似这个结构的旧项目,本地调试每次都死锁,而且我这个是很久之前的asp.net不是现在的asp.net core,旧项目死锁的问题我在网上找到了解决方式加了.ConfigureAwait(false)后正常了,原因是asp.net中的上下文竞争导致的相互阻塞,于是我就试着自己模拟死锁加深理解,但是自己写的小例子却无法触发死锁,完全不知道是怎么回事了 _

支持(0) 反对(0) WmW | 园豆:424 (菜鸟二级) | 2021-12-02 17:29
0

我的理解是,iis会把请求放到一个队列里面,你来个请求我给你封装一个对象,放入管道中,不管处理完没有,继续接受下一个请求了,每次请求都是对于ash.x都是独立的。而且iis里有线程池,如果请求数量没有超过这个线程池的线程数量极限,是不会阻塞的。如果你想发生死锁,可以找一个互斥资源,让两个请求几乎同时去请求这个资源,并且互相都不释放这个资源,就可能会死锁。

HelloLLLLL | 园豆:434 (菜鸟二级) | 2022-01-01 11:01
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册