Подтвердить что ты не робот

Увеличивать значение счета за пределами параллели.

Как я могу прирастить целочисленное значение вне рамки цикла parallel.foreach? Каков самый легкий способ синхронизации доступа к объектам за пределами параллельных циклов?

var count = 0;
Parallel.ForEach(collection, item =>
{
  action(item);
  // increment count??
}
4b9b3361

Ответ 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));
});