Увеличивать значение счета за пределами параллели.
Как я могу прирастить целочисленное значение вне рамки цикла parallel.foreach? Каков самый легкий способ синхронизации доступа к объектам за пределами параллельных циклов?
var count = 0;
Parallel.ForEach(collection, item =>
{
action(item);
// increment count??
}
Ответы
Ответ 1
Мне нравится бить мертвых лошадей!:)
"Самый легкий" способ увеличить счетчик из нескольких потоков:
Interlocked.Increment(ref count);
Но, как указывали другие, если вы делаете это внутри Parallel.ForEach
, то вы, вероятно, делаете что-то неправильно.
Я подозреваю, что по какой-то причине вы используете ForEach
, но вам нужен индекс для обрабатываемого элемента (он никогда не будет работать с Parallel.ForEach
). Я близко? Зачем вам нужен счет? Какую магию VooDoo вы пытаетесь сделать?
UPDATE:
Кажется, что вы находитесь в безопасности с ConcurrentDictionary
, если ваш ключ равен URI
, а значение TAnswer
. Я не вижу проблемы, пока вы не пытаетесь использовать счетчик для ссылок на элементы в своей коллекции.
Наконец-то...
Если вам нужен счетчик, используйте цикл Parallel.For
... он безопасно увеличивает счетчик для вас.
Ответ 2
Используйте Interlocked.Increment
.
Я бы не увеличивал вещи внутри параллельного foreach (если, конечно, вы не используете Interlocked.Increment или какой-либо другой механизм блокировки). Это не для чего. Параллельный foreach должен запускаться только с действиями, которые не вызывают побочных эффектов в общем состоянии. Чтобы увеличить значение в параллельном foreach, вы столкнетесь с самой проблемой, которую вы, скорее всего, избегаете.
Ответ 3
Используйте метод Interlocked.Increment таким образом.
int count = 0;
Parallel.ForEach(users, (u) =>
{
var currentCount = Interlocked.Increment(ref count);
Log(String.Format("Step {0} of {1}", currentCount, users.Count));
});