我在非异步页面中使用以下基于任务的编程(TPL)。
我的问题是:在ASP中使用TPL(即任务并行库)创建多线程调用可以吗。Net页面,或者必须始终使用内置的异步页面功能在ASP中进行多线程处理。网页到目前为止,TPL方法没有产生任何问题,但只是想确定一下,以防我在ASP中使用TPL时错过了一些重要的点/隐藏的风险。网页。
Task.Factory.StartNew(() =>
{
try
{
Method1();
success4 = true;
}
catch (Exception e4)
{
success4 = false;
ex = e4.ToString();
}
}),
Task.Factory.StartNew(() =>
{
try
{
Method2();
success5 = true;
}
catch (Exception e5)
{
success5 = false;
ex = e5.ToString();
}
}),
Task.Factory.StartNew(() =>
{
try
{
Method3();
success6 = true;
}
catch (Exception e6)
{
success6 = false;
ex = e6.ToString();
}
})
};
Task.WaitAll(tasks);
更新1:
如回答中所指出的,在ASP中使用第三方物流。Net将限制ASP的可扩展性。Net应用程序,因为每个任务都使用来自ASP。Net线程池,同时保持页面的原始线程处于阻塞状态
我现在正在考虑在异步页面中调用方法时使用TPL,如下面的代码所示,以利用并行带来的更强大的处理能力。但我将进一步研究这一点,看看在实际情况下,TPL是否会使异步方法变得更好或更糟。
private void DoTask4(object[] paras)
{
Parallel.Invoke(() =>
{
try
{
Method4( paras);
}
catch (Exception e4)
{
success4 = false;
//log the exception
}
});
}
IAsyncResult BeginAsyncOperation4(object sender, EventArgs e, AsyncCallback cb, object state)
{
task4 = new AsyncTaskDelegate(DoTask4);
IAsyncResult result = task4.BeginInvoke(state as object[], cb, "task4");
return result;
}
void EndAsyncOperation4(IAsyncResult ar)
{
task4.EndInvoke(ar);
if (success4 == null)
{
success4 = true;
}
}
void TimeoutAsyncOperation4(IAsyncResult ar)
{
success4 = false;
}
更新2:
最后,正如答案中所指出的,即使将TPL与Async页面方法一起使用,也会导致线程池中的线程被使用,这再次意味着我们的ASP。网络可伸缩性将是一个问题。因此,最好不要在异步页面中使用TPL。
这种方法可能会严重损害服务器的可扩展性,因为它使用了额外的空间并阻塞了请求线程。假设Method1..3
负责一些与IO绑定的工作。如果不能使用异步ASP。NET控制器,您仍然可以使用AsyncManager
(例如,像这样)或PageAsyncTask
(对于经典的ASP.NET)启动异步IO绑定操作,并避免阻塞。
但是,如果您需要做一些CPU绑定的工作(而不是IO绑定的工作),只需在同一个请求线程上一步一步地进行,而不是并行进行。否则,根据服务器负载,每个Task.Factory.StartNew
可能会搁置另一个传入的HTTP请求。因为您可能希望提供尽可能多的并发HTTP请求,所以应该避免并行化CPU绑定的工作。
也就是说,对于并发HTTP请求数量较少的intranet web应用程序来说,您的代码可能很好。如果您想加快单个请求的响应传递,可以这样做。