c# - 工作线程中 Excel Interop 的性能缓慢

标签 c# excel multithreading excel-interop

我在 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 对象交互时,您会返回到拥有线程,并使用调用 Excel 对象所需的任何数据,以便您的调用可以直接转到 Excel COM 服务器代码而不是被编码(marshal)。

关于c# - 工作线程中 Excel Interop 的性能缓慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42848953/

相关文章:

excel - VBA 宏 - 为生成的数据指定新工作表

excel - 通过引用列表中的工作表名称从其他工作表返回单元格值

database - 在ring网站中使用atom作为内存数据库

c# - Entity Framework Context 6.1.3 未刷新/销毁?

c# - .NET Core Web API 中的 OData 列表/字典序列化

c# - 我将如何对数据库逻辑进行单元测试?

excel - VBA Mac Excel 2016 : Chart . 导出权限被拒绝错误 70

c++ - 在函数返回之前解锁互斥锁可以增加并发吗?

c - 退出线程时检测到堆栈崩溃

c# - 使用 Wrapper 对象正确清理 excel interop 对象