如何停止打印直到页面计算完成
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
});
我正在用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
});