我读了很多东西,我想我了解发生了什么,但我不知道如何解决。
我有一个c#wpf应用程序。用户单击一个按钮,然后我启动另一个线程来做很多工作。其中一部分是打开excel,创建一个excel文件,然后对excel工作表进行很多设置。
完成该部分后,用户将使用该应用程序,并且有一些按钮可以进一步与excel文件进行交互,例如添加更多内容。
我的问题是当线程完成时,我将该COM对象丢失到excel文件中。不知道如何解决此问题。 这是我的代码(后来绑定到excel)
..我在excel对象上包含一个公共静态类
public static class MyGlobals
{
public static string ExcelprogID = "Excel.Application";
public static dynamic xlWorkBook;
public static dynamic xlApp;
}
..然后用户单击一个按钮,然后我启动另一个线程
private void btnSearch_Click(object sender, RoutedEventArgs e)
{
string dialogValues = "...";//replaced code for simplicity
Thread t = new Thread(() => workerthread(dialogValues));
t.SetApartmentState(ApartmentState.STA);
t.Start();
}
..然后在新线程中我做了很多,但是其中一件事是创建excel对象并设置excel表格。
private void workerthread(string e)
{
MyGlobals.xlApp = Activator.CreateInstance(Type.GetTypeFromProgID(MyGlobals.ExcelprogID));
MyGlobals.xlWorkBook = MyGlobals.xlApp.Workbooks.Add(MyGlobals.misValue);
MyGlobals.xlApp.Visible = true;
//more code here to do stuff with excel.
}
...这是我的问题发生的地方。现在返回主UI线程,用户可以单击按钮来操纵excel文件中的内容。但是我得到这个错误
private void btnPlaceBM_Click(object sender, RoutedEventArgs e)
{
//Excel.Worksheet BM;
dynamic BM;
try
{
BM = MyGlobals.xlWorkBook.Sheets["CADD Basemaps"];
}
catch
{
MessageBox.Show("Project Index Excel file was closed! Can not place any data to excel file!");
return;
}
}
这是我得到的错误
System.Runtime.InteropServices.InvalidComObjectException被捕获:“无法使用与其基础RCW分离的COM对象。”
有人可以给我一些帮助吗..我能以某种方式找回那个excel对象吗?
答案 0 :(得分:0)
好的评论让我开始思考。我试图查看如何在线程结束之前从工作线程获取COM对象。更改代码太困难了,因此在启动工作线程之前,UI线程会创建COM对象,因为在工作线程中途才能创建COM对象。然后它就撞到了我。当我到达创建COM对象的工作线程的那一部分时,就将其分派到UI线程。现在,这可能不是最佳解决方案,但它可以工作。 这是如何在辅助线程中执行此操作的代码段。
private void workerthread(string e)
{
//code removed for simplicity..
//Create COM object for excel app & excel workbook in Main thread to prevent object reference loss
App.Current.Dispatcher.Invoke((Action)delegate
{
MyGlobals.xlApp = Activator.CreateInstance(Type.GetTypeFromProgID(MyGlobals.ExcelprogID));
MyGlobals.xlWorkBook = MyGlobals.xlApp.Workbooks.Add(MyGlobals.misValue);
});
MyGlobals.xlApp.Visible = true;
//more code here to do stuff with excel.
}