簡體   English   中英

ThreadPool.QueueUserWorkItem - 訂單未保存?

[英]ThreadPool.QueueUserWorkItem - Order not preserved?

我只是注意到通過ThreadPool.QueueUserWorkItem排隊的回調順序不是確定性的,它肯定不是傳遞回調的順序。

這可以通過以下簡單程序進行驗證:

    private static void Main()
    {
        for (var i = 0; i < 10; ++i)
            ThreadPool.QueueUserWorkItem(Console.Write, i + " ");

        Thread.Sleep(1000);
    }

一次運行的輸出是:

0 3 8 9 1 2 5 4 6 7

該名稱表明訂單已保留。

有沒有辦法確保訂單得到保留?
如果沒有,您建議采用哪種替代實施方案?

沒有辦法保留訂單。 線程池的目的是並行執行獨立的任務。 從本質上講,這些任務的開始和結束順序是高度不確定的。 如果您需要子任務以特定順序開始和結束,那么您無法並行化它們。

private static void Main()
{
    for (var i = 0; i < 10; ++i)
        Console.Write(i + " ");

    Thread.Sleep(1000);
}

為了澄清:線程池隊列中的任務順序被保留,但它們實際執行的順序是不確定的。

如果您希望任務在串行但在與調用線程不同的線程上運行,那么您應該查看Reactive Extensions中EventLoopScheduler 它允許您在特定工作線程上安排工作單元。

我不確定是否保留了啟動任務的順序。 但是,由於所有排隊的工作項都是異步運行的,因此無論如何都無法保證執行的順序。

如果要保留訂單,一個選項是串行運行工作項, 而不是從線程池運行。 另一種是計划的第一個,等第二個作業...另一種是使用等待句柄的工作同步。

該名稱表明訂單已保留。

名稱中的“隊列”意味着在線程池線程中排隊等待執行的項目...這意味着 - 如果線程池線程忙於除了一個 - 在這種情況下,您的項目將按順序逐個排隊你把它們排隊了。 但是因為這不太可能是項目第一個可用的后台線程,然后同時執行。

暫無
暫無

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

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