C# 在异步任务中创建控件会导致死锁

C# 在异步任务中创建控件会导致死锁,c#,asynchronous,controls,deadlock,async-await,C#,Asynchronous,Controls,Deadlock,Async Await,预期结果将是: 任务 主异步 主要 但是,实际上没有调用任何Console.Writeline 即使我编写了一个windows窗体应用程序,也会发生同样的情况,它显然有一个win32消息循环 public partial class Form1 : Form { public Form1() { InitializeComponent(); } protected async override void OnLoad(EventArgs e)

预期结果将是:

任务 主异步 主要

但是,实际上没有调用任何Console.Writeline

即使我编写了一个windows窗体应用程序,也会发生同样的情况,它显然有一个win32消息循环

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    protected async override void OnLoad(EventArgs e)
    {
        await MainAsync();
        MessageBox.Show("Done!");
        base.OnLoad(e);
    }

    async static Task MainAsync()
    {
        await Task.Run(() => SomeTask());

    static async Task SomeTask()
    {
        TextBox tb = new TextBox();
        await Task.Delay(100);
    }
}

消息框从未出现。

Marc是正确的;现代Windows窗体控件在创建时将在其当前线程上建立WinForms
SynchronizationContext


因此,
SomeTask
将把它的继续调度到Win32消息循环上,但是没有线程处理该消息循环(例如,
Application.Run
);这意味着它将永远无法处理来自同步上下文的消息;同步上下文是。。。更新后的代码呢?它显然有一个win32消息循环,那么为什么它不工作呢?您仍然在另一个(非UI)线程上创建控件,而该线程没有win32消息循环。
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    protected async override void OnLoad(EventArgs e)
    {
        await MainAsync();
        MessageBox.Show("Done!");
        base.OnLoad(e);
    }

    async static Task MainAsync()
    {
        await Task.Run(() => SomeTask());

    static async Task SomeTask()
    {
        TextBox tb = new TextBox();
        await Task.Delay(100);
    }
}