异步CTP错误-任务永远不会完成
本文关键字:永远 任务 CTP 错误 异步 | 更新日期: 2023-09-27 18:11:38
首先向前道歉:我无法将以下错误隔离到一个简单的控制台应用程序中。然而,在我相对简单的ASP。NET Web窗体应用程序,以下代码将导致当前线程无限期阻塞:
public class MyModule : IHttpModule
{
public void Dispose()
{
}
public void Init(System.Web.HttpApplication context)
{
context.BeginRequest += this.Context_BeginRequest;
}
private void Context_BeginRequest(object sender, EventArgs e)
{
Sleep().Wait();
var x = 2; // This line is never hit.
}
private async Task Sleep()
{
await TaskEx.Run(() => System.Threading.Thread.Sleep(1000));
}
}
任务状态保持为"等待激活"。有人知道为什么会发生这种事吗?
编辑:Stephen Cleary的评论揭示了更多信息:
AspNetSynchronizationContext
是最奇怪的实现。它将Post视为同步而非异步,并使用锁一次执行一个委托。AspNetSynchronizationContext
不需要封送回同一线程(但需要获取锁(;Wait
上的死锁是因为延续正在等待锁(由事件处理程序中的线程持有(
我的猜测是有一个SynchronizationContext
,它强制延续在与事件处理程序相同的线程上运行。您的事件处理程序正在阻塞该线程,因此continuation永远不会运行,这意味着事件处理程序永远不会阻止。
不过,这只是一个猜测——这是我目前唯一能想到的有意义的事情。
尝试解锁的一个选项是将Sleep
方法更改为:
private async Task Sleep()
{
await TaskEx.Run(() => System.Threading.Thread.Sleep(1000))
.ConfigureAwait(continueOnCapturedContext: false);
}
这将允许在不同的背景下继续进行。
我很惊讶有这样的同步上下文,请注意。。。我希望所有这些都只发生在线程池中。CCD_ 6可能有轻微的特殊处理。