C# 替代后台工作人员报告进度和 COM 互操作?

问题描述 投票:0回答:1

背景: 我正在制作一个 C# 应用程序,将一系列单元格复制到位图图像中以进行报告。我的所有用户都在其计算机上安装了 Excel,因此 Excel COM 互操作是访问和呈现工作表的简单方法。我希望 COM 互操作在不同的线程上工作,这样它就不会锁定我的 winforms UI。最初,我尝试了后台工作程序,以便在处理每张工作表时向 UI 报告进度。我并不是尝试使用多线程来提高速度或异步处理多个工作簿。然而,我遇到了两个大问题。

  • range.CopyPicture 依赖于 Windows 剪贴板,这会导致非常零星的竞争情况。
  • Excel 互操作是单线程单元,但后台工作人员使用线程池。

我一直在阅读 TAP(基于任务的异步模式)和 EAP(基于事件的异步模式),但我无法将此信息应用到我的情况中。有什么替代方案可以同时允许 UI 进度报告并与 Excel COM 互操作良好地配合?

我当前使用后台工作者的代码:

private void worker_DoWork(object? sender, DoWorkEventArgs e)
{
    excelApp = new Excel.Application();

    Workbook workbook = excelApp.Workbooks.Open(workbookFilePath, ReadOnly: true);

    Worksheet mySheet = workbook.Sheets[1];

    worker.ReportProgress(10);

    Bitmap image = GenerateImageFromWorksheet(mySheet);

    image.Save(outputNamePath);
    
    workbook.Close(0);

    excelApp.Quit();

    worker.ReportProgress(100);
}

private Bitmap GenerateImageFromWorksheet(Worksheet mySheet)
{
    // A bunch of interop code

    Excel.Range myRange = mySheet.Range[mySheet.Cells[1, 1], mySheet.Cells[row, column]];

    myRange.CopyPicture(XlPictureAppearance.xlScreen, XlCopyPictureFormat.xlBitmap);

    return new Bitmap(GetClipboardData());
}
c# multithreading winforms backgroundworker excel-interop
1个回答
0
投票

我的问题的解决方案在这个相关但不同的问题的答案中得到了解决。请注意@Flydog57 和其他人在两篇文章中提到的陷阱。

如何将消息发布到运行消息泵的 STA 线程?

© www.soinside.com 2019 - 2024. All rights reserved.