我有以下winforms事件
public MainForm()
{
InitializeComponent();
new Form().ShowDialog(); // This causes the problem
}
private async void MainForm_Load(object sender, EventArgs e)
{
LoadingLabel.Text = "Initializing...";
try
{
await Task.Delay(500);
}
catch (Exception ex)
{
MessageBox.Show("Error initializing");
Environment.Exit(0);
}
Console.WriteLine(LoadingLabel.InvokeRequired);
}
期望:程序打印false
结果:程序打印true
。
据我了解,await应该将同步上下文设置回原始状态,并且不需要Invoke
。然而,这种情况并非如此。尝试更新LoadingLabel
的{{1}}属性会引发Text
。我错过了什么吗?
我使用的是.NET 4.5.2。
答案 0 :(得分:1)
在调用ShowDialog
后,会创建一个嵌套的消息循环,WindowsFormsSyncronizationContext
将替换为默认的SyncronizationContext
,导致您需要Invoke
。然后恢复上下文。进一步阅读How to get a Synchronization Context for the second form shown
你有一些选择:
(1)构建代码,以便在ShowDialog
事件或Load
中调用OnLoad override
。我认为这是最好的方法,可以长期为您服务。
(2)但是,您也可以这样做:
public MainForm() {
InitializeComponent();
var uiContext = SynchronizationContext.Current;
new Form().ShowDialog();
SynchronizationContext.SetSynchronizationContext(uiContext);
}
当对话框关闭时,这会简单地重置SyncronizationContext
。