簡體   English   中英

使用 Task.ContinueWith? 創建執行隊列

[英]Creating a execution queue by using Task.ContinueWith?

我有幾個要在后台執行的操作,但它們必須一個接一個地同步執行。

我想知道使用 Task.ContinueWith 方法來實現這一點是否是個好主意。 你預見到這有什么問題嗎?

我的代碼看起來像這樣:

private object syncRoot =new object();
private Task latestTask;

public void EnqueueAction(System.Action action)
{
    lock (syncRoot)
    {
        if (latestTask == null)
            latestTask = Task.Factory.StartNew(action);
        else
            latestTask = latestTask.ContinueWith(tsk => action());
    }
}

這有一個缺陷,我最近發現了自己,因為我也在使用這種方法來確保任務按順序執行。

在我的應用程序中,我有數千個這些迷你隊列的實例,並很快發現我遇到了 memory 問題。 由於這些隊列經常處於空閑狀態,我長時間持有最后完成的任務 object 並阻止垃圾收集。 由於最后完成的任務的結果 object 通常超過 85,000 字節,因此它被分配到大型 Object 堆(在垃圾收集期間不執行壓縮)。 這導致了 LOH 的碎片化,並且該過程的規模不斷擴大。

作為避免這種情況的一種技巧,您可以在鎖內真正的任務之后安排一個無操作任務。 對於真正的解決方案,我將需要采用不同的方法來控制調度。

這應該按設計工作(如果相應的任務已經完成,TPL 將立即安排繼續)。

就個人而言,在這種情況下,我只會使用使用並發隊列( ConcurrentQueue )的專用線程來從中提取任務 - 這更明確但更容易解析閱讀代碼,特別是如果你想找出即當前有多少任務排隊等.

我使用了這個片段並且似乎讓它按設計工作。 在我的情況下,實例的數量不會達到數千,而是個位數。 盡管如此,到目前為止沒有任何問題。

我會對 ConcurrentQueue 示例感興趣,如果有的話?

謝謝

暫無
暫無

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

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