异步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));
    }
}

任务状态保持为"等待激活"。有人知道为什么会发生这种事吗?

异步CTP错误-任务永远不会完成

编辑: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可能有轻微的特殊处理。