【问题标题】:Is it possible to use multicore inside of one Excel instance?是否可以在一个 Excel 实例中使用多核?
【发布时间】:2013-01-07 00:39:20
【问题描述】:

我必须对 10,000 多个 Excel 文件应用简单的格式。我已经有一个多核程序正在运行。它为每个 Excel 文件打开一个新的 Excel 实例。如果重要的话,这段代码目前在我的表单代码中。

我希望将一个 Excel 实例与许多工作簿一起使用。如果我只使用一个 Excel 实例,是否可以使用多核功能?如何?

-如果上面的答案是否定的,一个更复杂的问题可能是:我应该生成多少个 Excel 实例,以及如何在每个实例之间拆分工作簿?

这里的当前代码:

private void SelectFilesButtonClick(object sender, EventArgs e)
{
   var listOfExcelFiles = OpenExcel.FileNames.ToList();
   Parallel.ForEach(listOfExcelFiles, TrivialExcelEditFunction);
}

private void TrivialExcelEditFunction(string file)
{
   //Open instance of Excel
   //Do processing
   //Close instance of Excel
}

更新了下面的代码,但仍然没有将自身限制为正确的内核数量。不知道为什么。

private void SelectFilesButtonClick(object sender, EventArgs e)
{
   var listOfExcelFiles = OpenExcel.FileNames.ToList();
   int cores = Environment.ProcessorCount;

   //Split one list into list of lists. Number of lists based on number of cpu cores
   List<List<object>> listOfLists = Split(listOfExcelFiles, cores);

   //Limits number of threads to number of cores
   Parallel.ForEach(listOfLists, new ParallelOptions { MaxDegreeOfParallelism = cores }, EditExcel);
}

private void TrivialExcelEditFunction(string file)
{
   //Open instance of Excel

   foreach (string file in files)
   {
       //Do processing
   }
   //Close instance of Excel
}

假设我有 4 个核心。我的想法是将文件列表分成 4 个相等的列表,将线程限制为 4 个,然后我就可以在 4 个 Excel 实例中处理文件。我认为这意味着 TrivialExcelEditFunction 只会运行 4 次。相反,这个函数运行了 14 到 27 次。请告诉我哪里出错了。

【问题讨论】:

    标签: c# excel multicore


    【解决方案1】:

    创建 N 个任务/线程来执行处理,其中“N”是您机器上的内核数。给每个任务/线程一个Excel 的实例。

    您将无法从多个线程控制单个实例(至少不能高效;它一次只能处理一个线程的任务),并且创建如此多的 Excel 实例效率非常低。

    【讨论】:

    • 我应该为每个物理核心还是每个逻辑核心创建一个实例?
    • @Brandon 很可能是合乎逻辑的,但在实践中只需尝试两者,看看哪个更快。
    • 使用新代码更新问题。仍然没有运气。您是否有机会提供更多帮助?
    • @Brandon 只需抓取您用来启动新实例的代码。创建 N 个线程/任务,在每个线程/任务中创建一个 excel 实例。让该线程处理 1/N 个文件。等待所有线程/任务。不要使用Parallel.Foreach
    【解决方案2】:

    正如@Servy 指出的那样,您可以创建多个线程,每个线程一个 Excel 实例。

    确保每个线程都创建它正在使用的 Excel 对象。

    期待奇怪。拥有 10,000 多个文件,您可能至少会遇到一些小问题。如果隐藏的 Excel 实例试图提示用户,它可能会显示为已冻结。

    Word 在使用调用单线程 COM 对象的某些函数时会出现一些问题,我怀疑 Excel 可能也有一些问题。在 Word 中,这些表现形式多种多样,包括实例冻结或关闭。

    如果格式真的很简单并且您的文件是 xmlx,那么编写一些代码以通过 OOXML SDK 应用更改可能是可行的,这不需要实际的 Excel 实例

    【讨论】:

    • 在批处理时处理错误的最合乎逻辑的方法似乎是存储哪些文件遇到错误并通知用户他们需要手动执行哪些文件。
    • @Brandon 这将是最好的方法,是的,除了你需要一个看门狗线程来检测你的一些工作线程是否被冻结。当你不恰当地关闭一个 COM 对象时,你会得到严重的内存泄漏
    【解决方案3】:

    我认为这就是上面@Servy 所指的内容。我现在每天都在我正在使用的一段代码中使用它,它确实可以处理 Excel,而且肯定还没有失败。还要确保正确编组 COM 对象。 还有一点额外的信息,Excel 2010 内部使用多核,注意性能(尤其是大文件)。

    var tasks = new Task[Environment.ProcessorCount];
    
    for (int i = 0; i< Environment.ProcessorCount; i++)
    {
        tasks [i] = Task.Factory.StartNew(() =>
        {
            // your Excel code here.                 
        });
    }
    
    Task.WaitAll(tasks);
    

    【讨论】:

    • 工作完美。无需重复打开和关闭 Excel 的开销,我将处理时间从每 3 秒 1 个文件减少到每秒 5 个文件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-08-17
    • 2013-03-04
    • 2020-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多