工作线程中 Excel Interop 的性能缓慢
Slow performance of Excel Interop in worker thread
我在工作线程中遇到 Excel Interop 的性能非常慢。
这是我在 VSTO 项目中的代码,它只读取指定单元格的值(例如 'Sheet1!A1'):
private object test(string sheetRange = "Sheet1!A1")
{
var targetRange = sheetRange.Split('!');
if (targetRange.Length != 2) { return null; }
var sheetname = targetRange[0];
var address = targetRange[1];
var workbook = Application.ActiveWorkbook;
var sheet = (Excel.Worksheet)workbook.Worksheets[sheetname];
var cell = sheet.Range[address];
return cell.Value;
}
当我在 UI 线程中 运行 这段代码时,它运行得非常快。
但是一旦它在工作线程中达到运行,性能就非常糟糕(大约慢 x50 - x100)。
Thread thread = new Thread(() =>
{
test();
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
thread.Join(int.MaxValue);
Marshal.ReleaseComObject没有执行,因为这是测试代码。
我的代码有什么不好的地方吗?
或者有什么方法可以避免工作线程中的性能问题?
谢谢
您正在跨越两个 STA 线程之间的 COM 边界。 COM 必须整理所有调用,这可能会非常昂贵。
如果您必须在与拥有原始 Excel 对象的线程不同的线程中具有 Excel 相关逻辑,那么您应该自己做编组。 IE。在该工作线程中执行您需要的任何后台逻辑,但要确保当您与 Excel 对象交互时,您会返回到拥有线程,并使用调用 [=16] 所需的任何数据=] 对象,以便您的调用可以直接转到 Excel COM 服务器代码,而不是被编组。
我在工作线程中遇到 Excel Interop 的性能非常慢。
这是我在 VSTO 项目中的代码,它只读取指定单元格的值(例如 'Sheet1!A1'):
private object test(string sheetRange = "Sheet1!A1")
{
var targetRange = sheetRange.Split('!');
if (targetRange.Length != 2) { return null; }
var sheetname = targetRange[0];
var address = targetRange[1];
var workbook = Application.ActiveWorkbook;
var sheet = (Excel.Worksheet)workbook.Worksheets[sheetname];
var cell = sheet.Range[address];
return cell.Value;
}
当我在 UI 线程中 运行 这段代码时,它运行得非常快。 但是一旦它在工作线程中达到运行,性能就非常糟糕(大约慢 x50 - x100)。
Thread thread = new Thread(() =>
{
test();
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
thread.Join(int.MaxValue);
Marshal.ReleaseComObject没有执行,因为这是测试代码。
我的代码有什么不好的地方吗? 或者有什么方法可以避免工作线程中的性能问题?
谢谢
您正在跨越两个 STA 线程之间的 COM 边界。 COM 必须整理所有调用,这可能会非常昂贵。
如果您必须在与拥有原始 Excel 对象的线程不同的线程中具有 Excel 相关逻辑,那么您应该自己做编组。 IE。在该工作线程中执行您需要的任何后台逻辑,但要确保当您与 Excel 对象交互时,您会返回到拥有线程,并使用调用 [=16] 所需的任何数据=] 对象,以便您的调用可以直接转到 Excel COM 服务器代码,而不是被编组。