1

I am attempting to execute multiple (n) tasks asynchronously which aggregate to a single summed result. Currently I have the following:

public class Foo
{
    public async void DoWork()
    {
        var stopwatch = Stopwatch.StartNew();
        List<Task> tasks = new List<Task>();

        var bar = new Bar();

        for (int i = 0; i < 20; i++)
        {
            var task = Task.Run(() =>
            {
                Thread.Sleep(500);

                bar.Count1++;
                bar.Count2++;
            });

            tasks.Add(task);
        }

        await Task.WhenAll(tasks.ToArray());

        Console.WriteLine("All done, Bar Count1: " + bar.Count1 + ", Count2: " + bar.Count2);
        stopwatch.Stop();
        Console.WriteLine("Time taken " + stopwatch.ElapsedMilliseconds + " ms");
    }
}

public class Bar
{
    public int Count1 { get; set; }
    public int Count2 { get; set; }
}

I would expect bar.Count1 and bar.Count2 to have values of 20 at the end of execution here, however, each time I run the program I get different values for each of them (which are most of the time < 20). How do I get around this problem?

kspearrin
  • 10,238
  • 9
  • 53
  • 82
  • If your tasks are truly CPU-bound, then I recommend using `Parallel` or PLINQ, both of which have aggregation support built-in. – Stephen Cleary May 20 '14 at 23:42

1 Answers1

4

Nothing closure problem here. ++ operator is not thread safe. So you need a lock around it.

lock(bar)
{    
    bar.Count1++;
    bar.Count2++;    
}

That should solve the problem.

Community
  • 1
  • 1
Sriram Sakthivel
  • 72,067
  • 7
  • 111
  • 189
  • Had these been fields instead of properties you also could have used `Interlocked.Increment(` and not need to lock (just in case the OP's real case involved fields instead of properties). – Scott Chamberlain May 19 '14 at 04:09
  • 1
    @ScottChamberlain True, but OP needs it as public. Public fields is not a good option. One way is to have increment logic inside `Bar` class itself. – Sriram Sakthivel May 19 '14 at 04:11