[英]ASP.NET C# thread aborted exception?
我正在嘗試建立一個小的電子郵件工作者來發送我的電子郵件。 電子郵件工作程序在其自己的線程中運行。 global.asax啟動線程,然后運行一輪,然后拋出此異常。 我一直在嘗試找出將它扔到哪里,但是每次看起來都不同。 記錄被打印到文本文件中,以便工作,也許是處理功能?
這是引發的異常:
在電子郵件工作者循環中開始新的一輪
在電子郵件工作者循環中入睡
mscorlib.dll中發生類型'System.Threading.ThreadAbortException'的第一次機會異常
mscorlib.dll中發生類型'System.Threading.ThreadAbortException'的異常,但未在用戶代碼中處理
這是EmailWorker的代碼
public static class EmailWorker
{
public static void Work()
{
TimeSpan sleepTime = new TimeSpan(0, 1, 0);
for (; ; )
{
Debug.WriteLine("Starting a new round in the email worker for-loop");
try
{
// Get the records
CS_Code.UtopiaDataContext db = new CS_Code.UtopiaDataContext();
List<CS_Code.Global_Email> emailsToSend = (from xx in db.Global_Emails select xx).ToList();
// Write the records to a file (for now)
TextWriter writer = new StreamWriter(@"test.txt", true); // For debugging
foreach (var email in emailsToSend)
writer.WriteLine("To: " + email.Email_Address + ", Subject: " + email.Subject + ", uid:" + email.UserName.ToString());
writer.Close();
writer.Dispose();
// Delete the used records from the database
foreach (var email in emailsToSend)
db.Global_Emails.DeleteOnSubmit(email);
db.SubmitChanges();
db.Dispose();
Debug.WriteLine("Going to sleep in the email worker for-loop");
Thread.Sleep(sleepTime); // Sleep for 1 minute.
Debug.WriteLine("Just woke up in the email worker for-loop");
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
break;
}
}
}
}
這是啟動所有內容的global.asax文件:
private static Thread EmailWorkerThread { get; set; }
void Application_Start(object sender, EventArgs e)
{
// Email worker thread
if ((EmailWorkerThread == null) || (!EmailWorkerThread.IsAlive))
{
ThreadStart ts = new ThreadStart(EmailWorker.Work);
EmailWorkerThread = new Thread(ts);
EmailWorkerThread.Start();
}
}
void Application_End(object sender, EventArgs e)
{
// Email worker thread
if ((EmailWorkerThread != null) || (EmailWorkerThread.IsAlive))
EmailWorkerThread.Abort();
EmailWorkerThread = null;
}
您需要將EmailWorker移出ASP.NET並移到Windows服務中。 您可以通過WCF在網頁和服務之間進行通信。 ASP.NET不適用於長時間運行的任務。
當您的應用程序關閉並調用EmailWorkerThread.Abort()
時,將發生ThreadAbortException
。 這是預期的行為,它發生在隨機的位置,因為當Application_End
在線程上調用Abort()
時,代碼可能位於不同的“位置”。
根據MSDN , ThreadAbortException
是一個特殊的異常,即使在您的代碼處理之后,該異常也總是被拋出。 目的是讓您知道線程正在關閉,以便您有機會進行清理。
您的應用程序可能已關閉,因為IIS在設置了一定的空閑時間或某些其他限制后關閉了工作進程。 同樣,這是可以預期的,ASP.NET應用程序往往具有“有限的生存期”,因此,像這樣長時間運行的線程並不是一個好主意。
我不確定您的確切問題是什么,但希望我能回答。
您正在創建的線程被asp.net中止。 在asp.net中,創建長時間運行的線程是一個主要的禁忌。
A我們有一個可行的解決方法,我們不為此感到驕傲...創建一個計時器來處理未決的電子郵件。
static Timer processTimer; // declare static at service level
// At the static constructor:
processTimer = new Timer(new TimerCallback(TimerTick), 60000, 10000, defaultInterval); //wait a minute before begin (dueTime = 60000)
要特別小心,在Timer_Tick事件中,最多處理N封電子郵件,因此計時器滴答結束,並且新的滴答出現……
這正在我們的生產環境中進行...
子線程僅在父線程處於活動狀態時才能存在。 即使您在似乎是應用程序級別的位置上定義了一個線程,我也無法想象該線程實際上可以在HttpRequest線程之外生存。 對我來說,這意味着您的請求線程終止時,您的子級EmailWorkerThread終止。 由於線程處於休眠狀態,因此下一行嘗試執行,但由於HttpRequest線程已經運行,因此無法執行。
ThreadAbortException
顧名思義,當線程正在工作並且中止時拋出該異常。 這發生在這個地方:
EmailWorkerThread.Abort();
無法捕獲它,並且在應用程序結束時會發生。
更好的實現是將無限循環替換為可取消循環。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.