![](/img/trans.png)
[英]Fire and forget, using `Task.Run` or just calling an async method without `await`
[英]Fire & Forget method using Task.Run not working
我讀了很多嘗試使用Task.Run
的代碼, Task.Run
沒有成功。
我要達到的目標:
我嘗試過並且不了解為什么它不起作用的原因:
protected void btn_Click(object sender, EventArgs e) { // Some actions // Should insert a record in database --> OK //Tried this call with and without ConfigureAwait(false) Task.Run(() => MyClass.doWork()).ConfigureAwait(false); // Should insert a record in database --> OK // Some actions not blocked by the previous call } public static class MyClass { public static void doWork() { // Should insert a record in database --> NOT INSERTED } }
protected void btn_Click(object sender, EventArgs e) { // Some actions // Should insert a record in database --> OK Bridge.call_doWork(); // Should insert a record in database --> OK // Some actions not blocked by the previous call } public static class Bridge { public static async Task call_doWork() { //Tried this call with and without ConfigureAwait(false) await Task.Run(() => MyClass.doWork()).ConfigureAwait(false); } } public static class MyClass { public static void doWork() { // Should insert a record in database --> NOT INSERTED } }
因此,我調用了Fire&Forget方法,該方法應該在數據庫中插入一條記錄,但是沒有插入任何記錄。
調用Fire&Forget方法之前和之后的插入均已完成。
我不知道該如何解決我的問題。
HttpContext
在主線程以外的其他線程中將不可用,因此您不能依賴它。
但是,您可以在啟動任務時將數據從HttpContext
傳遞到您的方法。 例如:
Task.Run(() => MyClass.doWork(HttpContext.Current.Session["somedata"])).ConfigureAwait(false);
為什么沒有通過HttpContext調用獲得EventViewer事件? 我在使用HostingEnvironment.QueueBackgroundWorkItem而不是Task.Run時得到了一個。
OK,首先,如果你有QueueBackgroundWorkItem
可用,為什么你會永遠使用Task.Run
用於發射后不管的工作?
正如我在博客上所描述的Task.Run
,在ASP.NET上使用Task.Run
進行即發即Task.Run
是一個非常糟糕的主意 ! QueueBackgroundWorkItem
是最低可行的解決方案,只有在您接受不可靠性的情況下才可以。
QueueBackgroundWorkItem
做了幾件事情對你以后Task.Run
:它注冊到ASP.NET運行時的工作(其中最小化,但並不能消除工作將無法完成的可能性),它捕獲異常並記錄他們為你(這就是為什么您看到事件通知的原因。
因此,您看到一個異常事件,因為QBWI正在為您這樣做。 而使用Task.Run
代碼,則將捕獲異常並將其放置在返回的Task
(應該如此),然后您的代碼完全忽略了該任務,從而靜默地吞下了該異常。
是! 我使用HttpContext來獲取Session。 但是我不能在不更改大量代碼的情況下進行更改。
正如其他人指出的那樣, HttpContext
僅在請求上下文內有效。 因此,當您顯式運行后台代碼時,它當然沒有請求上下文。 根據定義,后台代碼必須獨立於請求。
但是,我認為您還忽略了另一個非常重要的考慮因素:
public static void doWork()
{
// Should insert a record in database --> NOT INSERTED
}
如果doWork
偶爾不執行,您確定您的應用程序完全正常嗎? 因為這就是后台任務發生的事情。 ASP.NET旨在響應請求,而不是運行后台任務。
因此,每逢一次藍月亮,都不會顯示應該由doWork
插入的記錄。 如果這是不可接受的,那么您就不應該一勞永逸。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.