我有以下 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
.
Result:程序打印true
.
据我了解,await 应该将同步上下文设置回原来的状态,而不是Invoke
应该是必需的。然而,这种情况并非如此。正在尝试更新LoadingLabel
's Text
属性抛出一个InvalidOperationException
。我错过了什么吗?
我正在使用.NET 4.5.2。
拨打电话后ShowDialog
,这会创建一个嵌套消息循环WindowsFormsSyncronizationContext
替换为默认值SyncronizationContext
导致你需要一个Invoke
。然后上下文会被恢复。进一步阅读如何获取所示的第二种形式的同步上下文 https://stackoverflow.com/questions/4513021/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
当对话框关闭时返回。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)