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

时间:2010-10-05 09:43:20

标签: c# multithreading .net-3.5

我需要从另一个线程(Excel Interop)“发送”一段代码到UI线程来执行。通常,您在实现Invoke界面的Form上使用ISynchronizeInvoke

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

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

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

当输入CodeExecutedByUIThread时,我们仍处于UI线程中,因此理论上所需的一切都应该存在。不幸的是Form is the only class implementing that interface,是吗?

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

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

更新:哦,我知道,让SynchronizationContext对象看起来就像SynchronizationContext.Current一样简单,它不需要对表单的任何引用。因此,我会更多地了解如何使用它。

1 个答案:

答案 0 :(得分:2)

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

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

MainForm main = new MainForm();
EnvironmentService.UI = main;
EnvironmentService.UIContext = SynchronizationContext.Current;
Application.Run(main);