这是我第一次处理大型多线程项目,所以请耐心等待。我们正在编写一个窗口服务,它将在数据库表上循环,并根据找到的记录生成SSRS报告。我试图把它写成一个多线程系统。
// THIS IS LONG RUNNING TASK
void ProcessReport(Report report)
{
ReportExecutionService rs = new ReportExecutionService();
rs.Credentials = new NetworkCredential(id,pass);
rs.Url = "url...asmx";
rs.ExecutionHeaderValue = new ExecutionHeader();
rs.Timeout = Timeout.Infinite;
string historyID = null;
ExecutionInfo info = rs.LoadReport("/../ReportName", historyID);
}
在ProcessReport()方法内部,我调用ReportExecutionService并生成SSRS报告。这是一项长期运行的任务,最多可能需要12个小时。这是选项1为我想要生成的每个REPORT打开新线程。我们将限制我们打开的线程数
foreach(Report report in reportList)
{
if (report.ReportID != null)
{
Thread thread = new Thread(() => ProcessReport(report));
thread.Start();
}
}
问题:
答案 0 :(得分:1)
我对多线程的所有不同选项感到不知所措 像TASK,BackgroundWorker,Thread,ThreadPool。有没有更好的办法 实现我的目标比我上面的目标?
我明白你的意思。有很多方法可以在.NET中进行多线程工作。如果您正在寻找 parallalism ,请务必检查Task Parallel Library,因为它提供了与ThreadPool相比的另一个抽象级别以及一般的线程使用。如果您正在寻找并发(这正是您需要的),请查看async-await并研究其工作原理。
这是调用Reporting Web Service的有效方法吗?
高效是一个广义的术语,取决于您从中查看的视角。基本上,不需要在多个线程中执行HTTP请求只是为了让您的应用程序保持响应。由于网络IO本质上是异步的,因此您可以公开自己的非阻塞异步方法。
例如,它可能如下所示:
public class ReportExecutionService
{
private readonly HttpClient httpClient = new HttpClient();
public async Task<ExecutionInfo> LoadReportAsync(string reportName, string historyId)
{
// Lets assume you're sending the report as a JSON,
// and the return type is also a JSON
var content = new { ReportName = reportName, HistoryId = historyId };
var response = await httpClient.PostAsJsonAsync(
$"http://www.apiaddress.com/{reportName}", content);
var jsonResponse = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<ExecutionInfo>(jsonResponse);
}
}
现在ProcessReport
也变成了异步方法:
public Task<ExecutionInfo> ProcessReportAsync(Report report)
{
ReportExecutionService rs = new ReportExecutionService
{
Credentials = new NetworkCredential(id, pass),
Url = "url...asmx",
ExecutionHeaderValue = new ExecutionHeader(),
Timeout = Timeout.Infinite
};
string historyID = null;
return rs.LoadReportAsync("/../ReportName", historyID);
}
现在你可以这样称呼它:
public async Task ProcessAllReports()
{
var reportTasks = reportList.Select(report => ProcessReportAsync(report));
ExecutionInfo[] reports = await Task.WhenAll(reportTasks);
// Do stuff with the reports.
}