C# 如何在不引用表单的情况下使用ISynchronizeInvoke
我需要从另一个线程(Excel Interop)向UI线程“发送”一段代码以执行。通常,您会在C# 如何在不引用表单的情况下使用ISynchronizeInvoke,c#,multithreading,.net-3.5,C#,Multithreading,.net 3.5,我需要从另一个线程(Excel Interop)向UI线程“发送”一段代码以执行。通常,您会在表单上使用Invoke,该表单实现了ISynchronizeInvoke接口: public class MyForm : Form { ... private void Button_Click(object sender, EventArgs e) { SomeExcelWorkbook.OnBeforeClose += delegate(ref bool C
表单
上使用Invoke
,该表单实现了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);
};
}
当输入UI线程执行的代码时,我们仍然在UI线程中,因此理论上所有需要的东西都应该在那里。不幸的是,是吗
如何从UI线程中获取ISynchronizeInvoke
或者有没有办法获取同步上下文?我将如何检索和使用它
更新:哦,我明白了,获取SynchronizationContext对象看起来就像
SynchronizationContext.Current
一样简单,它不需要任何表单引用。所以我会在谷歌上搜索更多关于如何使用它的信息。一般来说,我认为两者都不可能
这似乎是一个显而易见的答案,但我们在本例中使用的是在应用程序启动时将SynchronizationContext和对表单的引用(作为ISynchronizeInvoke)存储在静态类中
MainForm main = new MainForm();
EnvironmentService.UI = main;
EnvironmentService.UIContext = SynchronizationContext.Current;
Application.Run(main);
哦,我明白了,获取SynchronizationContext对象看起来相当简单,因此即使没有对表单的引用也应该可以工作。要小心,因为使用SynchronizationContext。辅助线程上的Current将无法获取所需的上下文,这就是我建议在应用程序启动时从主线程存储它的原因。很好,同时,我们也在网络资源中阅读了该警告。