簡體   English   中英

使用Task.Run的Fire&Forget方法不起作用

[英]Fire & Forget method using Task.Run not working

我讀了很多嘗試使用Task.Run的代碼, Task.Run沒有成功。

我要達到的目標:

  • 在ASP.NET WebForm事件(單擊事件處理程序)中,調用Fire&Forget方法(不阻止當前的執行流)。

我嘗試過並且不了解為什么它不起作用的原因:


第一版:

 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM