简体   繁体   中英

Why do these tasks execute sequentially?

Why does the following code execute sequentially?

List<Task> tasks = new List<Task>();

for (int i = 0; i <= max; i += block)
{
    if (i + block >= max)
        tasks.Add(Task.Factory.StartNew(() => Count(ref counter, block)));
    else
        block = max - i;
}

Task.WaitAll(tasks.ToArray());

I have also tested a version of this using Parallel.Invoke ; it, too, fails to execute in parallel. There's bound to be something I'm not understanding, but when I try Googling this, I mostly get instructions on how to force sequential execution.

As a response to one of the caveats given in an answer below, I have included the following method for reference:

static void Count(ref int counter, int num)
{
    int localCounter = 0;
    for (int i = 0; i < num; i++)
        if (Coin()) localCounter++;
    System.Threading.Interlocked.Add(ref counter, localCounter);
}

Edited again: Thank you all!

Just replace tasks.Add(Task.Factory.StartNew(() => Count(ref counter, block))); with Console.WriteLine and debug your code.

You never create more than one task.

for (int i = 0; i <= max; i += block)
{
    if (i + block >= max)
        Console.WriteLine(i);
    else
        block = max - i;

}

why does the following code execute sequentially?

It doesn't, unless you have something within the Count method that's synchronizing access to a single resource. If it can be parallelized, then this will run in parallel.

If Count executes very quickly then you'll find that the tasks are finished faster than new tasks get scheduled, which is why they may all execute in order.

Seems to me there is something wrong with your loop/if statement:

for (int i = 0; i <= max; i += block)
{
    if (i + block >= max)
        tasks.Add(Task.Factory.StartNew(() => Count(ref counter, block)));
    else
        block = max - i;
}

If I am reading it right, you will only add a task if i + block >= max and you will only loop if i + block <= max (showing both the counter increase and the condition check). As such you will only add a task once.

In addition, you are changing block when you are not adding a task. I expect you want something more like the following, though I can not be sure without more code:

for (int i = 0; i <= max; i += block)
{
    tasks.Add(Task.Factory.StartNew(() => Count(ref counter, block)));
    if (i + block >= max) { block = max - i; }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM