等待处理0x800AC472错误的c#Excel互操作替代方案
我有一个应用程序可以多次写入公式/宏加载工作簿。在每次迭代中,它对一些数据进行3次循环,创建、填充、保存,然后关闭一个excel文件。当它是自身运行的唯一版本时,它可以正常工作,但如果有多个实例在运行,它就会出现问题 具体地说,我在将数据写入某些单元格时遇到0x800AC472错误。每次都不是相同的单元格或值,但每次似乎都是第二次通过。以下是相关代码:等待处理0x800AC472错误的c#Excel互操作替代方案,c#,excel,C#,Excel,我有一个应用程序可以多次写入公式/宏加载工作簿。在每次迭代中,它对一些数据进行3次循环,创建、填充、保存,然后关闭一个excel文件。当它是自身运行的唯一版本时,它可以正常工作,但如果有多个实例在运行,它就会出现问题 具体地说,我在将数据写入某些单元格时遇到0x800AC472错误。每次都不是相同的单元格或值,但每次似乎都是第二次通过。以下是相关代码: public void SetCellValue(int row, int col, string val) { if (_currWo
public void SetCellValue(int row, int col, string val)
{
if (_currWorkSheet != null)
{
string parms = string.Format("row={0}; col={1}; val={2}", row.ToString(), col.ToString(), val);
for (short i = 0; i < _maxRetries; i++)
{
try { (_currWorkSheet.Cells[row, col] as Range).Value2 = val; return; }
catch (Exception ex) { HandleError(ex, parms); }
}
Exception newExc = new Exception("Too many retries attempting to set cell value.");
newExc.Data.Add("parms", parms);
throw newExc;
}
}
private void HandleError(Exception exc, string parms)
{
if (exc != null && exc.Message != null)
{
// Excel error that just needs more time to complete. http://social.msdn.microsoft.com/forums/en-US/vsto/thread/9168f9f2-e5bc-4535-8d7d-4e374ab8ff09/
if (exc.Message.Contains("0x800AC472"))
Thread.Sleep(_threadSleepMs); // Give excel a chance to catch up, then keep processing.
else
{
Exception newExc = new Exception("Unexpected Error", exc);
newExc.Data.Add("parms", parms);
throw newExc;
}
}
}
public void SetCellValue(int行、int列、string val)
{
如果(_!=null)
{
字符串参数=string.Format(“行={0};列={1};val={2}”,行.ToString(),列.ToString(),val);
对于(短i=0;i<\u maxRetries;i++)
{
尝试{({u currsheet.Cells[row,col]作为范围)。Value2=val;return;}
catch(Exception ex){HandleError(ex,parms);}
}
Exception newExc=新异常(“尝试设置单元格值的重试次数太多”);
newExc.Data.Add(“parms”,parms);
抛出newExc;
}
}
私有无效句柄错误(异常exc,字符串参数)
{
if(exc!=null&&exc.Message!=null)
{
//Excel错误,需要更多时间才能完成。http://social.msdn.microsoft.com/forums/en-US/vsto/thread/9168f9f2-e5bc-4535-8d7d-4e374ab8ff09/
如果(exc.Message.Contains(“0x800AC472”))
Thread.Sleep(_threadSleepMs);//给excel一个迎头赶上的机会,然后继续处理。
其他的
{
异常newExc=新异常(“意外错误”,exc);
newExc.Data.Add(“parms”,parms);
抛出newExc;
}
}
}
我已经将_maxRetries设置为10,_threadSleepMs设置为500,并继续得到错误,因此我认为增加它不再有意义
我想知道是否有其他方法可以替代睡眠线程,让它有机会得到“脱钩”,因为它是
也许这可以作为第二个问题,但我不太关心这个问题,但是当它崩溃时,我仍然在finally块中对它执行Close(),但我仍然有它的实例。我是这样关闭它的:
public void Dispose()
{
if (!_disposed)
{
if (_currWorkBook != null)
for (short i = 0; i < _maxRetries; i++)
{
try { _currWorkBook.Close(false, _missing, _missing); break; }
catch (Exception ex) { HandleError(ex, ""); }
}
if (_app != null)
{
if (_app.Workbooks != null)
for (short i = 0; i < _maxRetries; i++)
{
try { _app.Workbooks.Close(); break; }
catch (Exception ex) { HandleError(ex, ""); }
}
for (short i = 0; i < _maxRetries; i++)
{
try { _app.Quit(); break; }
catch (Exception ex) { HandleError(ex, ""); }
}
if (_currWorkSheet != null)
{
Marshal.ReleaseComObject(_currWorkSheet);
_currWorkSheet = null;
}
if (_currWorkBook != null)
{
Marshal.ReleaseComObject(_currWorkBook);
_currWorkBook = null;
}
Marshal.ReleaseComObject(_app);
_app = null;
}
GC.Collect();
_disposed = true;
}
}
public void Dispose()
{
如果(!\u已处置)
{
如果(_currWorkBook!=null)
对于(短i=0;i<\u maxRetries;i++)
{
尝试{u currWorkBook.Close(false,{u missing,{u missing);break;}
catch(Exception ex){HandleError(ex,“”;}
}
如果(_app!=null)
{
如果(_app.workbook!=null)
对于(短i=0;i<\u maxRetries;i++)
{
尝试{u app.Workbooks.Close();break;}
catch(Exception ex){HandleError(ex,“”;}
}
对于(短i=0;i<\u maxRetries;i++)
{
尝试{u app.Quit();break;}
catch(Exception ex){HandleError(ex,“”;}
}
如果(_!=null)
{
Marshal.ReleaseComObject(当前工作表);
_currWorkSheet=null;
}
如果(_currWorkBook!=null)
{
Marshal.ReleaseComObject(当前工作簿);
_currWorkBook=null;
}
Marshal.ReleaseComObject(_应用程序);
_app=null;
}
GC.Collect();
_这是真的;
}
}
它不会抛出和出错,所以我只是想知道它是否有任何漏洞
谢谢,,
Jeff根据我的经验,当多个实例由COM Interop驱动时,Excel无法可靠运行。我们有很多测试代码,都是在Excel上运行的,所以我们试着让它运行起来。唯一的解决办法是将应用程序一次限制为一个实例——即使如此,我的经验是偶尔会出现无法解释的异常 也许能解决你的问题。SpreadsheetGear有一个“工作簿集”,大致类似于Excel应用程序,支持从不同线程使用任意数量的工作簿集 如果您想亲自试用,您可以查看ASP.NET的实时示例并下载免费试用版
免责声明:我拥有SpreadsheetGear LLC我能想到的唯一解决方案是在线程需要使用excel功能时在其上创建锁。这确保了我一次只有一个使用excel的进程。它并不完美,特别是当不相关的流程也尝试使用excel时,但这是我唯一能想到的解决方法。您经常会遇到此错误,因为您试图在同步文件夹(例如,在公司桌面中的主文件夹)上处理Office文档 只需先将文件复制到本地磁盘文件夹(如temp),一切正常 如果要更新Excel工作簿,或等待数据表或数据透视表刷新,请使用一些人为延迟 e、 g
field.ClearAllFilters();
Thread.Sleep(500);
Application.DoEvents();
field.CurrentPageName = value;
Thread.Sleep(500);
Application.DoEvents();