-1

While playing with the Parallel library, I came across unexpected results from Task Factory.

Assumption: Task Factory will process calls randomly

Result: Sequential processing every single time (whether the same function or different functions)

    static void Do(string test)
    {
        Console.WriteLine("testttttt " + test);
    }

    static void Main(string[] args)
    {
        Task.Factory.StartNew(() =>
        {
            Do("1"); Do("2"); Do("3"); Do("4"); Do("5");
            Do("1"); Do("2"); Do("3"); Do("4"); Do("5");
            Do("1"); Do("2"); Do("3"); Do("4"); Do("5");
        });
        Console.ReadKey();
    }

enter image description here

The following code produces random results:

        Task.Factory.StartNew(() =>
        {
            Do("1"); Do("2"); Do("3"); Do("4"); Do("5");
        });
        Task.Factory.StartNew(() =>
        {
            Do("1"); Do("2"); Do("3"); Do("4"); Do("5");
        });
        Task.Factory.StartNew(() =>
        {
            Do("1"); Do("2"); Do("3"); Do("4"); Do("5");
        });

enter image description here

Why the first example always produce sequential results and should this be taken for granted everything time?

Community
  • 1
  • 1
usefulBee
  • 9,250
  • 10
  • 51
  • 89

2 Answers2

5

The first example creates a single task. The code inside the single task will execute sequentially since a single thread is used by the task.

The second example creates 3 tasks. The code in each task will execute sequentially. But between different tasks, you get the "random" behavior.

Yacoub Massad
  • 27,509
  • 2
  • 36
  • 62
  • Does this mean that I should always assume that a single task is always tied to a single thread!? I tested using the following line and processing appears sequential as well: new Task(delegate{ Do("1"); Do("2"); Do("3");}).Start(); – usefulBee Apr 12 '16 at 20:25
  • 1
    I wouldn't generalize this for all `Task`s since some tasks can create other tasks inside of them. But for your case, since you are using `Task.Factory.StartNew` and providing an action to execute, the code inside the action will be tied to a single thread. – Yacoub Massad Apr 12 '16 at 20:29
  • "since some tasks can create other tasks inside of them." True. – usefulBee Apr 12 '16 at 20:31
3

In your first example you're calling one synchronous method in a thread pool thread, and exposing the results of the execution of that synchronous method asynchronously to the caller of Task.Factory.StartNew. The method itself is just a synchronous method, and will run accordingly. Since that method is synchronous, and the operations are all running from a single thread, that they run in order is guaranteed by C#.

When you start multiple tasks, without waiting for previous ones to finish, then the order of those operations is not guaranteed (unless the code in those operations explicitly synchronizes with each other).

Servy
  • 202,030
  • 26
  • 332
  • 449