You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在.NET 5控制台应用中复现异步死锁?

.NET 5 控制台应用异步死锁最小复现代码

默认.NET 控制台应用的同步上下文为null,await 完成后会直接在线程池线程上继续执行,因此默认不会触发ASP.NET/WinForms场景下的经典异步死锁。要复现对应死锁,需要先模拟单线程同步上下文,完整可运行代码如下:

using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;

// 模拟UI/ASP.NET Classic的单线程同步上下文行为
class SingleThreadSynchronizationContext : SynchronizationContext
{
    private readonly BlockingCollection<(SendOrPostCallback Callback, object State)> _taskQueue = new();
    private readonly Thread _runThread = Thread.CurrentThread;

    public override void Post(SendOrPostCallback d, object state) => _taskQueue.Add((d, state));

    public override void Send(SendOrPostCallback d, object state)
    {
        if (Thread.CurrentThread == _runThread)
        {
            d(state);
            return;
        }
        using var waitHandle = new ManualResetEventSlim(false);
        Post(_ =>
        {
            d(state);
            waitHandle.Set();
        }, null);
        waitHandle.Wait();
    }

    public void StartProcessing()
    {
        foreach (var task in _taskQueue.GetConsumingEnumerable())
        {
            task.Callback(task.State);
        }
    }

    public void StopProcessing() => _taskQueue.CompleteAdding();
}

class Program
{
    static async Task DemoAsync()
    {
        // await会捕获当前单线程同步上下文,等待完成后将剩余逻辑提交到上下文队列执行
        await Task.Delay(100);
    }

    static void Main(string[] args)
    {
        // 为当前主线程设置自定义单线程同步上下文
        var syncContext = new SingleThreadSynchronizationContext();
        SynchronizationContext.SetSynchronizationContext(syncContext);

        try
        {
            // 异步方法同步等待,触发死锁
            DemoAsync().Wait();
        }
        finally
        {
            syncContext.StopProcessing();
        }
        Console.WriteLine("程序执行完成(死锁状态下永远不会输出该行)");
    }
}

死锁原因说明

  • 主线程调用DemoAsync().Wait()后,会阻塞单线程同步上下文的唯一执行线程,等待DemoAsync任务执行完成
  • Task.Delay(100)计时结束后,需要把DemoAsync的剩余逻辑提交到单线程同步上下文的队列中等待执行
  • 同步上下文的唯一执行线程已经被Wait()阻塞,无法处理队列中的任务,DemoAsync永远无法执行完成,形成永久死锁

内容的提问来源于stack exchange,提问作者Leonardo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 19:45:05