簡體   English   中英

將異常或消息從線程/任務傳遞到主線程

[英]Passing exception or message from thread/task to main thread

我們正在Windows服務(.net 4.0)中處理和上傳大文件。 處理和上傳步驟可能需要幾分鍾才能完成。 管理員可以直接在數據庫中將作業標記為已取消,但要清除內存隊列中的作業則需要重新啟動服務。 目標是放棄該作業並在不重新啟動服務的情況下選擇隊列中的下一個作業。 這是我想做的:

在主入口點,啟動兩個任務:

Task processTask = Task.Factory.StartNew(ProcessJob);

Task monitorTask = Task.Factory.StartNew(MonitorDB);

ProcessJob將調用多個長時間運行的步驟,例如ProcessFile,UploadFile。 我們正在檢查步驟之間的作業狀態,但是作業可能卡在了這些長時間運行的步驟之一中。

如果monitorTask在DB中檢測到作業狀態更改,則應(通過異常或消息)將其傳達給主線程,以便主線程可以退出,將自身從處理隊列中刪除並允許隊列中的下一個作業啟動。 如果不等待,則不能進入異常,但不能等待,因為需要並行運行這些任務。 目前,我們不擔心ProcessJob中的某些同步步驟可能仍在進行並且最終可能完成的事實。 我們將用代碼來處理。

到目前為止,在我所有的應用程序中,我都使用Task.ContinueWith進行成功和失敗,但從未必須與主線程進行通信。

您可以通過BlockingCollection<T>在監視器線程和主線程之間進行通信。

這是我寫的一個簡單示例。

BlockingCollection<string> queue =
    new BlockingCollection<string>();

// monitor thread.
Task.Factory.StartNew(() =>
{
    while (true)
    {
        Thread.Sleep(1000);
        queue.Add("event occured.");
    }
});

// main thread.
while (true)
{
    // blocks when no messages are in queue.
    string message = queue.Take();

    // kill process thread here.
}

您可以為此使用CancellationToken 如果查看Task類,則有一個重載,您可以在其中傳遞CancellationToken 在您的服務中存儲對此令牌的引用,只需讓您的上傳/處理例程定期檢查令牌是否已被取消,如下所示:

if (yourToken.IsCancellationRequested)
    break;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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