如何在不引用Form的情况下使用ISynchronizeInvoke

chi*_*oro 6 c# multithreading .net-3.5

我需要从另一个线程(Excel Interop)"发送"一段代码到UI线程来执行.通常情况下,你会使用InvokeForm,它实现了ISynchronizeInvoke接口:

public class MyForm : Form
{
    ...
    private void Button_Click(object sender, EventArgs e)
    {
        SomeExcelWorkbook.OnBeforeClose += delegate(ref bool Cancel)
        {
            this.Invoke(someCode);
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,在表单代码和定义事件处理程序的代码之间有一层抽象,我在那时没有对表单的引用:

public void CodeExecutedByUIThread()
{
    ISynchronizeInvoke sync;
    SomeExcelWorkbook.OnBeforeClose += delegate(ref bool Cancel)
    {
        sync.Invoke(someCode);
    };
}
Run Code Online (Sandbox Code Playgroud)

进入时CodeExecutedByUIThread,我们仍处于UI线程中,因此理论上所需的一切都应该存在.不幸的是,Form是实现该接口的唯一类,是吗?

如何ISynchronizeInvoke从UI线程中获取?显然Thread.CurrentThread不提供它......

或者有办法获得SynchronizationContext?我该如何检索和使用它?

更新:哦,我明白了,获取SynchronizationContext对象看起来很简单SynchronizationContext.Current,不需要对表单进行任何引用.因此,我会更多地了解如何使用它.

mat*_*ash 2

总的来说,我认为这两者都不可能。

这似乎是一个显而易见的答案,但我们在本例中使用的是在应用程序启动时将 SynchronizationContext 和对 Form 的引用(作为 ISynchronizeInvoke)存储在静态类中。

MainForm main = new MainForm();
EnvironmentService.UI = main;
EnvironmentService.UIContext = SynchronizationContext.Current;
Application.Run(main);
Run Code Online (Sandbox Code Playgroud)