这是一个.ashx处理程序,它创建一系列Task对象,然后在foreach循环中执行。
List<Task<Action>> list = new List<Task<Action>>();
list.Add(Task.Factory.StartNew<Action>(() => AddHeader(graphics, request, reportParameters)));
list.Add(Task.Factory.StartNew<Action>(() => AddSubmitter (graphics, request, reportParameters)));
list.Add(Task.Factory.StartNew<Action>(() => AddActivity(graphics, request, reportParameters)));
list.Add(Task.Factory.StartNew<Action>(() => AddCharts(graphics, request, reportParameters)));
//Task.WaitAll(list.ToArray()); //AY - This seems unnecessary
foreach (var action in list.Select(t => t.Result))
{
action();
}
返回Action的每个方法都会执行CPU密集型工作,如下面的第一个方法。
private Action AddHeader(XGraphics graphics, HttpRequest request, ReportParameters reportParameters)
{
DataSet ds = new myData().ClientHeader(reportParameters);
// This will be a function waiting to be called.
return () =>
{
// Some CPU intensive operation code here.
};
}
有人可以帮我理解这段代码是否有用 1)从异步或多任务角度来看? 2)此代码是否甚至从ASP.NET线程池创建多个线程?
当我调试应用程序时,它在运行foreach循环之前在我的机器上显示4个单独的任务。每个任务都会检索数据集,我认为这是因为每个方法中的部分代码都在return()Action语句之前运行。
此代码的全部目的是在执行每个CPU密集型操作方法之前在单独的任务中启用多个数据库调用吗?或者代码真的在做异步的东西吗?
答案 0 :(得分:1)
这不是利用代表线程池执行单元的任务的最佳方式:
foreach (var action in list.Select(t => t.Result))
将阻止执行,直到它从每个任务顺序获得Result
。这意味着返回的操作一旦准备执行就不会被执行,它们将按照添加到列表中的顺序执行,否则如果我们一旦执行它们就可能获得的任何潜在优势准备好了。所以,作为结论:
这样的代码只是以资源效率最低的方式启动了4个数据库调用,然后浪费了4个错误使用的线程池线程来执行它们的&#34; continuation&#34;原始线程中的顺序没有利用4任务可以按任意顺序执行的可能性。
P.S。:即使您真的需要进行CPU密集型处理,也不要使用Factory.StartNew - 使用Task.Run。这不是实际错误,因为它们基本上做同样的事情,而是a good recommendation。