我有问题。我有应用程序,生成带有报告服务的pdf。它工作正常,但需要大约20-60秒。生成一个pdf。这次是报告服务中的错误的结果。当我需要一个网上的pdf,或者一晚上需要300个时,没关系,但现在我需要制作,生成7278个文件。在一个线程中,它将花费大约4天(大约96小时)。我需要让它在一个晚上(8-12h)工作。我在考虑多线程。
关于代码。长时间运行的任务(生成pdf)在特殊的Web服务中生成,由控制台应用程序执行。控制台应用程序,首先获取客户端列表(clientsId)和raport endDate。
代码:
DateTime batchDate = new DateTime(year, month, 1).GetEndOfMonthDate();
int[] clientsId = GetClientsIds(batchDate);
SaveLogFile(batchDate);
LogProcessingStart(clientsId);
int successedCount = 0;
int processingCount = 1;
CreateReportsDirectoryIfNecessary(ReportDir);
int i = 0;
while (i < clientsId.Length)
{
try
{
logger.Trace(string.Format("Przetwarzanie klient_id = {0}. {1}/{2}", clientsId[i], processingCount, clientsId.Length));
ExecuteRequest(batchDate, clientsId[i]);
logger.Trace(string.Format("Koniec przetwarzania klient_id = {0}", clientsId[i]));
successedCount++;
}
catch (SoapException ex)
{
logger.Trace(string.Format("Błąd przetwarzania klient id = {0}.", clientsId[i]));
logger.Trace(string.Format("Szczegóły : {0}", ex.Actor));
}
catch (Exception ex)
{
logger.Trace("Błąd " + ex.Message);
}
i++;
processingCount++;
Thread.Sleep(TaskDelaySeconds * 1000);
}
protected override void ExecuteRequest(DateTime batchDate, int clientId)
{
bool success = false;
for (int i = 0; i < 10 && success == false; i++)
{
try
{
var result = gateway.GetPlatformReport(clientId, batchDate);
string reportPath = ReportDir + "/" + result.ReportName + ".pdf";
File.WriteAllBytes(reportPath, result.Report);
success = true;
}
catch (Exception ex)
{
string origAssemblyLocation = Assembly.GetExecutingAssembly().CodeBase;
logger.Trace("Błąd generowania raportu. Szczegóły " + ex.Message);
logger.Trace(string.Format("Próbuje jeszcze raz.. (Retry = {0})", i + 1));
}
}
}
在执行“gateway.GetPlatformReport(clientId,batchDate)”的ExecuteRequest(batchDate,clientsId [i])中生成长时间运行的任务(生成pdf)(执行Web服务并按照客户端请求执行20-60秒) )。控制台应用程序和Web服务都在同一台机器上。
目前,我有7278个客户,整个过程需要4天。
答案 0 :(得分:2)
您可以尝试使用并发for循环替换while循环。
Parallel.For(0, clientsId.Length, i =>
{
// While body.
});
有关详细信息,请参阅:https://msdn.microsoft.com/en-us/library/Ff963552.aspx和https://msdn.microsoft.com/en-us/library/system.threading.tasks.parallel.for%28v=vs.110%29.aspx
答案 1 :(得分:2)
除非Web服务可以同时处理多个请求,否则在客户端中使用Parallel.For
将无法帮助您。确保Web服务在多个线程上运行多个请求,然后您可以像在其他人建议的那样在客户端中使用Parallel.For。
那就是说,我会查看PDF生成代码。每个文件60秒是非常多的,也许你可以加快它。
更新:另一个选项 如果您的Web服务已经处理并发调用,则根本不需要更改客户端应用程序 - 只需运行控制台应用程序的多个实例,并为每个实例提供一组不同的项目。
答案 2 :(得分:1)
看看Parallel.For。此构造类似于for循环,但会自动处理工作负载的分区并在多个线程上运行代码。
Parallel.For(0, clientsId.Length, i => ExecuteRequest(batchDate, clientsId[i]));