我需要从另一个线程(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
一样简单,它不需要对表单的任何引用。因此,我会更多地了解如何使用它。
答案 0 :(得分:2)
总的来说,我认为两者都不可能。
这似乎是一个明显的答案,但我们在这种情况下使用的是在应用程序启动时将SynchronizationContext和对Form的引用(作为ISynchronizeInvoke)存储在静态类中。
MainForm main = new MainForm();
EnvironmentService.UI = main;
EnvironmentService.UIContext = SynchronizationContext.Current;
Application.Run(main);