我正在为excel开发一个VSTO加载项。我已经使用后台工作线程在后台执行一些代码,以便用户可以同时在Excel工作表上自由工作。
我使用主代码中的sheet_activate事件处理程序为单元格更改和选择更改事件注册了侦听器,如代码所示:`
private void thisWorkbook_SheetActivate(Object sheet1)
{
try
{
if (sheet1 is Worksheet)
{
Worksheet sheet = sheet1 as Worksheet;
sheet.SelectionChange += eventDel_SelectionChange;
sheet.Change += eventDel_CellsChange;
}
}
catch (Exception e)
{
printException(e);
}
}`
在运行后台工作线程之前,会按预期触发这些事件。但是,在运行后台工作线程之后,不会以某种方式触发这些事件。
我必须再次执行 thisWorkbook_SheetActivate 来解决此问题。每次运行后台工作线程后我都必须这样做。我的后台工作程序中的代码片段分析工作表中已存在的数据,进行一些更改,然后更新工作表中的数据。
我确实知道excel使用COM(组件对象模型)和STA(单线程单元)来执行线程,即一次只能在公寓中执行一个线程。我不确定这是否可能导致问题。
有人可以解释为什么会这样吗?有哪些解决方案可以解决这个问题?
我目前正在使用Microsoft Visual Studio 2010和Microsoft Excel 2007。
提前致谢!
答案 0 :(得分:0)
如果您正在访问诸如范围之类的excel方法或在后台线程上更新单元格,那么您将遇到问题。到目前为止,您很幸运,代码没有崩溃和/或抛出异常。我很确定它会抛出异常,你可能无法捕获它。 至于解决方案,您需要做的是从事件处理程序中获取所需的工作表中的所有数据,然后在后台线程中使用该“数据”,并且不要从bgnd线程访问excel UI。当线程完成其工作时,您需要一些如何在主UI线程上调用方法(有很多关于如何使用Invoke委托更新主UI线程控件的示例)。
答案 1 :(得分:0)
事件的发送者(在您的情况下为工作簿)必须存储在字段中,而不是存储在局部变量中才能被处置。放置对象后,事件就消失了。