C# VSTO:在Excel主线程上调用
我在Excel工作表上有一个按钮,它启动一个新线程进行一些处理。如果我想对Excel进行任何更改(例如,使用C# VSTO:在Excel主线程上调用,c#,excel,vsto,C#,Excel,Vsto,我在Excel工作表上有一个按钮,它启动一个新线程进行一些处理。如果我想对Excel进行任何更改(例如,使用工作表.Range(“A1”).Value=“info”)将数据写入单元格),我想我必须使用主UI线程 如何做到这一点 通常在Winforms中,我会在控件上调用Invoke,但是Excel.Application或工作表或范围对象没有Invoke方法。您是否尝试过从按钮启动BackgroundWorker?这使得它非常容易,因为ProgressChanged和RunWorkerCompl
工作表.Range(“A1”).Value=“info”
)将数据写入单元格),我想我必须使用主UI线程
如何做到这一点
通常在Winforms中,我会在控件上调用
Invoke
,但是Excel.Application
或工作表
或范围
对象没有Invoke
方法。您是否尝试过从按钮启动BackgroundWorker?这使得它非常容易,因为ProgressChanged和RunWorkerCompleted事件将在主线程上触发
我没有在Excel/VSTO环境中尝试过这一点,但我不明白为什么它不起作用。这项工作不需要在UI线程上完成,.net将为您封送调用,但如果您从后台线程重复调用,则可能会遇到性能问题 但要具体回答您的问题,如果您有.net 3.5,请在加载项加载事件中添加以下内容:
Dispatcher _dispatcher = Dispatcher.CurrentDispatcher;
然后添加:
public Dispatcher Dispatcher { get {return _dispatcher;} }
然后,您可以通过
Globals.ThisAddIn.Dispatcher.Invoke(()=>{/*stuff*/});
如果没有.net 3.5,那么还有一些其他线程同步技术,比如使用SynchronizationContext.Current而不是Dispatcher。这是我使用WindowsForms为VSTO加载项提供的解决方案。 您不需要任何System.Windows.Forms.Control来使用它:
在此类中初始化addin:
Globals.ThisAddIn.TheWindowsFormsSynchronizationContext.Send(d =>
{
MyMethodToInvoke();
}, null);
将此行添加到“ThisAddIn_启动”函数:
this.TheWindowsFormsSynchronizationContext = WindowsFormsSynchronizationContext.Current
?? new WindowsFormsSynchronizationContext();
添加此新属性:
public SynchronizationContext TheWindowsFormsSynchronizationContext { get; private set; }
那么工作线程中的用法是:
Globals.ThisAddIn.TheWindowsFormsSynchronizationContext.Send(d =>
{
MyMethodToInvoke();
}, null);
第二种解决方案(未测试):您也可以使用:
Globals.ThisAddIn.TheWindowsFormsSynchronizationContext.Send(d =>
{
MyMethodToInvoke();
}, null);
希望有帮助,Jörg回答得很好。我一直在为类似的东西(xll插件)把头撞在墙上,这就解决了问题。正如您所说,虽然工作不需要在UI线程上完成,但如果您在另一个线程上完成,您可能会发现Excel.exe在关闭应用程序后仍然挂在任务管理器中。对于任何对
Dispatcher
感到困惑的人,您必须添加对WindowBase
的引用才能访问Dispatcher
类。当从其他线程调用时,我遇到的问题是Excel经常很忙,并抛出COMException。这就解决了问题。@JakeGinnivan我在VS2019
中使用你对我的VSTO
项目的建议。您要求在加载项的加载事件中添加\u dispatcher
变量声明。你是说在班级层面上申报吗?否则,属性声明public Dispatcher{get{return{u Dispatcher;}}
无法识别\u Dispatcher
,因为VS2019
正在抱怨我的VSTO
项目。如果我遗漏了什么,请告诉我。非常感谢!搜索了半个小时后,这是VSTO唯一可行的解决方案!SynchronizationContext似乎比Dispatcher更通用、更安全(可以从UI外部调用)。这里的VS-answer也适用于基于ExcelDna的插件。使用AutoOpen()函数初始化上下文,而不是此addin\u启动。