我有一個webform,我使用TPL在後臺發送電子郵件,因爲我們的SMTP服務器速度很慢,許多用戶最終都無法擺脫提交按鈕。在過去,我曾使用過System.Threading
和靜態方法來完成,這是一個類似任務 - 在.NET3.5,我的代碼是這樣的:關於在ASP.NET 4.0中使用任務並行庫的說明
Thread t = new Thread(new ParameterizedThreadStart(SendEmail));
t.Start(txtEmail.Text);
凡SendEmail的簽名是public static void AddEmailToMailingListInBackground(object EmailString)
和我所記得的方法必須是靜態的,並且我必須將TextBox txtEmail的值傳遞給異步方法,否則可能會失去對控件值的訪問權限,因爲頁面生命週期是獨立進行的。
現在使用System.Threading.Tasks
當我的代碼如下所示:
Task.Factory.StartNew(() => SendEmail(), TaskCreationOptions.LongRunning);
和SendEmail的簽名是private void SendEmail()
和我直接內的方法來訪問的txtEmail
的Text
財產。
我在這裏看到兩個主要區別。首先,我的異步方法不再必須是靜態的。其次,如果我使用線程,那麼在頁面的生命週期完成之後很長時間內,我就可以訪問該方法中頁面的控件值。這兩點讓我相信,在所有任務完成或頁面生命週期完成之前,頁面一直保持活動狀態,以先到者爲準。我已經通過調試並通過異步方法進行了測試 - 響應被髮送到瀏覽器,但我仍然能夠瀏覽並訪問控件及其值。 This MSDN article有一點幫助,但仍然沒有真正鞏固我對TPL與執行異步調用之前的.NET4方式發生的事情的理解。
任何人都可以告訴我,如果我的思想是正確的,這是在使用TPL和ASP.NET時的可靠行爲?
有人會關心進一步闡述嗎?
感謝德魯,特別是關於異常處理的警告。一些要求澄清。 1)在將try/catch塊中的SendMail調用封裝到SendMail中的行爲與try/catch塊中的SendMail的主體封裝相比,在使用OnlyOnFaulted選項的延續方面有什麼區別?我做了一些閱讀,發現當捕獲方法外部時,你應該尋找一個AggregateException [我認爲] – joelmdev 2012-02-23 14:49:18
@ jm2是的,那是真的。直接在SendMail任務中直接使用try/catch就可以直接使用同步代碼,所以異常將像vanilla .NET代碼一樣傳播。如果您使用ContinuationApproach,則執行SendMail任務時發生的任何異常都將由AggregateException包裝。如果你知道你的SendMail在下面是完全同步的,那麼如果你需要檢查它並對不同類型作出反應,你可以輕鬆/安全地從AggregateException :: InnerException屬性中取出原始異常。 – 2012-02-23 16:46:40
由於評論被破壞,部分內容部分2)您是否說直接訪問值是不安全的,因爲它們可能會發生變化?控制和它們的值是可用的我假設由於SynchronizationContext維護/恢復頁面狀態。 – joelmdev 2012-02-23 18:41:59