Асинхронная проблема с несколькими задачами

1

Я пытаюсь выполнить несколько (n) задач асинхронно, которые сводятся к одному суммированному результату. В настоящее время у меня есть следующее:

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; }
}

Я ожидал бы, что bar.Count1 и bar.Count2 будут иметь значения 20 в конце выполнения здесь, однако каждый раз, когда я запускаю программу, я получаю разные значения для каждого из них (которые большую часть времени <20). Как мне обойти эту проблему?

Теги:
async-await

1 ответ

4
Лучший ответ

Здесь нет проблемы с закрытием. ++ не является потокобезопасным. Поэтому вам нужен замок.

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

Это должно решить проблему.

  • 0
    Если бы это были поля вместо свойств, вы также могли бы использовать Interlocked.Increment( и не нужно блокировать (на тот случай, если реальный случай ОП включал поля вместо свойств).
  • 1
    @ScottChamberlain Верно, но OP нужен как публичный. Публичные поля не очень хороший вариант. Одним из способов является использование логики приращения внутри самого класса Bar .
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню