Winforms事件中未保留同步上下文 [英] Synchronization context not preserved in winforms event

查看:60
本文介绍了Winforms事件中未保留同步上下文的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下winforms事件

I have the following winforms event

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.

Expectation: Program prints false.
Result: Program prints true.

据我了解,await应该将同步上下文设置回原始状态,并且不需要Invoke.然而,这种情况并非如此.尝试更新LoadingLabelText属性将引发InvalidOperationException.我想念什么吗?

It is my understanding that await should set the synchronization context back to the original and no Invoke should be required. However, this is not the case. Attempting to update LoadingLabel's Text property throws an InvalidOperationException. Am I missing something?

我正在使用.NET 4.5.2.

I am using .NET 4.5.2.

推荐答案

在调用ShowDialog之后,这会创建一个嵌套的消息循环,将WindowsFormsSyncronizationContext替换为默认的SyncronizationContext,导致您需要.然后,上下文将在以后还原.进一步阅读如何获取广告的同步上下文显示的第二种形式

After the call to ShowDialog, which creates a nested message loop the WindowsFormsSyncronizationContext is replaced with the default SyncronizationContext causing you to need an Invoke. The context is then later restored. Further reading How to get a Synchronization Context for the second form shown

您有一些选择:

(1)构造代码,以便对ShowDialog的调用发生在Load事件或OnLoad override中.我认为这是最好的方法,可以长期为您服务.

(1) Structure your code so that the call to ShowDialog occurs in the Load event or in the OnLoad override. I think this is the best approach and would serve you well long term.

(2),但是,您也可以执行以下操作:

(2) However, you can also do this:

public MainForm() {
    InitializeComponent();
    var uiContext = SynchronizationContext.Current;
    new Form().ShowDialog();
    SynchronizationContext.SetSynchronizationContext(uiContext);
}

这仅在关闭对话框时将SyncronizationContext重设.

This simply resets the SyncronizationContext back when the dialog is closed.

这篇关于Winforms事件中未保留同步上下文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆