Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ThreadPool.QueueUserWorkItem - Order not preserved?

I just noticed that the order of callbacks queued via ThreadPool.QueueUserWorkItem is not deterministic, it certainly isn't the order the callbacks have been passed in.

This can be verified with the following simple program:

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

        Thread.Sleep(1000);
    }

The output of one run is:

0 3 8 9 1 2 5 4 6 7

The name suggests that the order is preserved.

Is there a way to make sure that the order is preserved?
If not, what alternative implementation do you suggest?

like image 906
Daniel Hilgarth Avatar asked Dec 04 '22 00:12

Daniel Hilgarth


2 Answers

If you want the tasks to run in serial but on a different thread than the calling thread, then you should look into the EventLoopScheduler in the Reactive Extensions. It allows you to schedule units of work on a particular worker thread.

like image 99
Wes Cumberland Avatar answered Dec 05 '22 13:12

Wes Cumberland


There is no way to preserve the order. The purpose of the thread pool is to execute independent tasks in parallel. The order in which those tasks start and finish is, by its nature, highly nondeterministic. If you need subtasks to start and finish in a particular order, then you can't parallelize them.

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

    Thread.Sleep(1000);
}

To clarify: the order of tasks within the thread pool queue is preserved, but the order in which they actually execute is nondeterministic.

like image 36
Peter Ruderman Avatar answered Dec 05 '22 13:12

Peter Ruderman