C# 在异步任务中创建控件会导致死锁
预期结果将是: 任务 主异步 主要 但是,实际上没有调用任何Console.Writeline 即使我编写了一个windows窗体应用程序,也会发生同样的情况,它显然有一个win32消息循环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)
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);
}
}