如何停止打印直到页面计算完成

How to Stop printing until calculation of pages finish

我正在用c#打印一个报表,报表有很多页,每一页都有复杂的计算。因为可能有很多页面,而且每个页面可能需要很长时间,所以我想异步进行计算。因为这是一个编码问题的工程问题,所以我删除了所有的混乱。这就是我的代码归结为:

  private void StartPrinting(object sender, PrintPageEventArgs e)
  {


     // calculate the total width and height of the printing area of the page

     // -1 just to be conservative
     documentWidth = CalculateDocumentWidth(printDocument, e) - 1;
     // -1 just to be conservative
     documentHeight = CalculateDocumentHeight(printDocument, e) - 1; 

     // calculate the columns and rows of all pages
     // some calculations ....

     // delegate to get results back
     DelegateToReportVoPageStructureDescription theDelegate 
        = ReportPageObjectCalculatedHandler;


     for (int i = 0; i < pageStructureObjects.Count; i++)
     {

        Task.Run(() =>
        {
           // call method to calculate each page here .... 
           // results returned by delegate to 
           // ReportPageObjectCalculatedHandler mehtod
        });

     }

  }

for循环在单独的线程中计算每个报表页面,然后每个计算过程的结果得出以下方法:

public void ReportPageObjectCalculatedHandler(VoReportPageObject  voReportPageObject, int pageIndex)
  {

     lock (thisLock) // thread safety
     {
        // assign the calculated page to local variable

        // count how many pages finished calculation

     }

     if ( all pages finished )
     {
        // now i can start printing
     }
  }

只有当所有页面都处理完毕后,我才能继续打印。现在您可能会问为什么我不在触发打印过程之前进行所有计算?那是因为我需要页面的尺寸才能进行任何处理。

我可以在 Task.Run(() 块之后进行循环以检查是否所有页面都已计算,但这不是一件好事。我需要一些方法来停止打印,直到所有页面计算完毕完成。

我该如何解决这个问题?

您可以将 Task.Run 调用返回的任务收集到数组中并使用 Task.WaitAll:

var tasks = new Task[pageStructureObjects.Count];
for (int i = 0; i < pageStructureObjects.Count; i++)
{
    tasks[i] = Task.Run(() =>
    {
       // call method to calculate each page here .... 
       // results returned by delegate to 
       // ReportPageObjectCalculatedHandler mehtod
    });
}
Task.WaitAll(tasks);

但是你所做的似乎是 Parallel.For 的完美候选者:

Parallel.For(0, pageStructureObjects.Count, i =>
{
    // call method to calculate each page here .... 
    // results returned by delegate to 
    // ReportPageObjectCalculatedHandler mehtod
});