.NET中的ThreadPool是基於隊列的工作池,但是它在ASP.NET主機進程內部使用,所以如果嘗試更多地使用ThreadPool,可能會降低Web Server的性能。
因此,您必須創建自己的線程,將其標記爲背景並讓其每隔幾秒輪詢一次工作可用性。
做的是,在數據庫如下創建工作表的最好辦法,
Table: JobQueue
JobID (bigint, auto number)
JobType (sendemail,calcstats)
JobParams (text)
IsRunning (true/false)
IsOver (true/false)
LastError (text)
JobThread類可以像下面。
class JobThread{
static Thread bgThread = null;
static AutoResetEvent arWait = new AutoResetEvent(false);
public static void ProcessQueue(Job job)
{
// insert job in database
job.InsertInDB();
// start queue if its not created or if its in wait
if(bgThread==null){
bgThread = new Thread(new ..(WorkerProcess));
bgThread.IsBackground = true;
bgThread.Start();
}
else{
arWait.Set();
}
}
private static void WorkerProcess(object state){
while(true){
Job job = GetAvailableJob(
IsProcessing = false and IsOver = flase);
if(job == null){
arWait.WaitOne(10*1000);// wait ten seconds.
// to increase performance
// increase wait time
continue;
}
job.IsRunning = true;
job.UpdateDB();
try{
//
//depending upon job type do something...
}
catch(Exception ex){
job.LastError = ex.ToString(); // important step
// this will update your error in JobTable
// for later investigation
job.UpdateDB();
}
job.IsRunning = false;
job.IsOver = true;
job.UpdateDB();
}
}
}
注意 不推薦用於高內存使用率任務此實現,ASP.NET會給大量內存的大任務不可用的錯誤,例如像我們有很多圖片上傳的,我們需要創建縮略圖並使用位圖對象處理它們,ASP.NET不會允許您使用更多內存,因此我們必須創建相同類型的Windows服務。
通過創建Windows服務,您可以創建相同的線程隊列並輕鬆利用更多內存,並且可以使用WCF或Mutex對象在ASP.NET和Windows Service之間進行通信。
MSMQ MSMQ也很大,但是它增加的配置任務,並且變得難以追查,有時錯誤。我們避免MSMQ,因爲我們花費很多時間在代碼中尋找問題的答案,在MSMQ配置存在問題的地方,錯誤有時不能提供足夠的信息,說明問題的確切位置。在我們的定製解決方案中,我們可以創建具有日誌的完整調試器版本來跟蹤錯而這是Managed Programs的最大優勢,在早期的Win32應用程序中,錯誤實際上很難追蹤。
由於我的回答從根本上離開了其他人,我誤解了你嗎?你能澄清嗎? 你是指並行執行(即多核,其他受訪者似乎假設)或卸載不是特定於當前請求的任務(在我讀的背景下運行)? –
@Jed:你是對的。正如我在下面所評論的,這不是關於多核,而是關注和即時性的過程分離。 – Alex