c#Excel Interop替代scheme等待处理0x800AC472错误

我有一个应用程序,写了很多次公式/macros载荷的工作簿。 它循环通过一些数据3次创build,填充,保存,然后在每次迭代closuresExcel文件。 当它是唯一运行的版本时,它可以正常工作,但是如果有多个它运行的实例,则会遇到问题。

具体来说,当向某些单元格写入数据时,出现0x800AC472错误。 每次都是不一样的单元格或者值,但是似乎每次都是第二遍。 这是相关的代码:

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; } } } 

我已经将_maxRetries设置为10,_threadSleepMs设置为500,并继续得到错误,所以我不认为增加它是有道理的。

我想知道是否有其他select,睡觉的线程,让它有机会“脱钩”,因为它是。

也许这可以作为第二个问题的资格,但我并不担心这个,但是当它崩溃时,我仍然在finally块上执行一个Close(),但是我仍然有它的实例悬而未决。 这是我如何closures它:

 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; } } 

它不会抛出和错误,所以我只是想知道它是否有任何漏洞?

谢谢杰夫

我能想出的唯一解决scheme是在线程需要使用excelfunction时创build一个锁。 这只是确保我只有一个使用excel的进程。 这不是完美的,特别是如果不相关的进程也尝试使用excel,但这是我能想出的唯一解决scheme。

根据我的经验,在COM Interop中驱动多个实例时,不能使Excel可靠地运行。 我们有很多testing代码是针对Excel运行的,所以我们试图让这个工作。 唯一的解决办法是一次只限制一个应用程序 – 即使如此,我的经验是,偶尔有一个无法解释的例外。

SpreadsheetGear for .NET可能会解决您的问题。 SpreadsheetGear有一个“工作簿集”,大致类似于Excel应用程序,并支持从不同线程使用的任意数量的工作簿集。

你可以在这里看到活的ASP.NET示例,如果你想自己试试,可以在这里下载免费试用版。

免责声明:我自己的SpreadsheetGear LLC

您经常可能会遇到此错误,因为您正在尝试使用同步文件夹上的Office文档(例如在企业桌面中的主文件夹)

首先将文件复制到本地磁盘文件夹(例如temp),然后全部都可以

如果您正在更新Excel工作簿,或正在等待数据表或数据透视表刷新使用一些人为延迟

例如

 field.ClearAllFilters(); Thread.Sleep(500); Application.DoEvents(); field.CurrentPageName = value; Thread.Sleep(500); Application.DoEvents();