Excel Interop在工作线程中的性能较慢

3

我在工作线程中遇到了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没有被执行,因为这是测试代码。

我的代码有什么问题吗? 还是有什么方法可以避免工作线程中的性能问题?

谢谢

1个回答

2
你正在两个STA线程之间跨越COM边界。COM必须对所有调用进行封送处理,这可能非常昂贵。
如果你必须在不同于拥有原始Excel对象的线程中具有与Excel相关的逻辑,则应该自己执行封送处理。也就是说,在工作线程中执行所需的后台逻辑,但请确保在与Excel对象交互时,返回到拥有线程,并使用所需的数据进行调用Excel对象,以便你的调用可以直接进入Excel COM服务器代码而不是被封送处理。

1
最后,我使用“同步上下文(SynchronizationContext)”来确保与Excel相关的逻辑在主线程中执行。 - user5466334

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接