Я пытаюсь выполнить несколько (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). Как мне обойти эту проблему?
Здесь нет проблемы с закрытием. ++ не является потокобезопасным. Поэтому вам нужен замок.
lock(bar)
{
bar.Count1++;
bar.Count2++;
}
Это должно решить проблему.
Interlocked.Increment(
и не нужно блокировать (на тот случай, если реальный случай ОП включал поля вместо свойств).Bar
.