在异步任务中创建控件会导致死锁
本文关键字:死锁 控件 创建 异步 任务 | 更新日期: 2023-09-27 18:20:16
预期结果为:
SomeTaskMainAsync主
class Program
{
static void Main(string[] args)
{
MainAsync().Wait();
Console.WriteLine("Main");
Console.ReadLine();
}
async static Task MainAsync()
{
await Task.Run(() => SomeTask());
Console.WriteLine("MainAsync");
}
static async Task SomeTask()
{
TextBox tb = new TextBox();
await Task.Delay(100);
Console.WriteLine("SomeTask");
}
}
但是,实际上并没有调用任何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);
}
}
MessageBox从未出现。
Marc是正确的;现代Windows窗体控件将在创建时在其当前线程上建立WinForms SynchronizationContext
。
因此,SomeTask
将调度其延续到Win32消息循环上,但没有线程处理该消息循环(例如,Application.Run
)。