В соответствии с 70-483 справочником экзамена:
Использование одновременных коллекций
При работе в многопоточной среде вам необходимо убедиться, что выне манипулировать общими данными одновременно без синхронизации доступа..NET Framework предлагает некоторые классы коллекций, созданные специально для использования в параллельных средах, что и есть, когда вы используете многопоточность. Эти коллекции являются поточно-ориентированными, что означает, что они внутренне используют синхронизацию, чтобы обеспечить доступ к ним для нескольких потоков одновременно.
Эти коллекции следующие: - BlockingCollection
ConcurrentBag
ConcurrentDictionary
ConcurrentQueue
ConcurrentStack
ConcurrentDictionary
A ConcurrentDictionary хранит пары ключ и значение в поточно-ориентированном режиме.Вы можете использовать методы для добавления и удаления элементов, а также для обновления элементов на месте, если они существуют.
Показывает методы, которые можно использовать для ConcurrentDictionary
var dict = new ConcurrentDictionary<string, int>();
if (dict.TryAdd("k1", 42))
{
Console.WriteLine("Added");
}
if (dict.TryUpdate("k1", 21, 42))
{
Console.WriteLine("42 updated to 21");
}
dict["k1"] = 42; // Overwrite unconditionally
int r1 = dict.AddOrUpdate("k1", 3, (s, i) => i * 2);
int r2 = dict.GetOrAdd("k2", 3);
При работе с ConcurrentDictionary у вас есть методы, которые могут атомарно добавлять, получать и обновлять элементы.Атомарная операция означает, что она будет запущена и завершена как один шаг без вмешательства других потоков.TryUpdate проверяет, является ли текущее значение равным существующему значению, прежде чем обновлять его.AddOrUpdate гарантирует, что элемент добавляется, если его там нет, и обновляется до нового значения, если он есть.GetOrAdd получает текущее значение элемента, если оно доступно;если нет, он добавляет новое значение, используя фабричный метод.
Итак, чтобы быть уверенным, что вы добавляете результат итерации, я напишу что-то вроде этого и, возможно, протестирую возвращение моегоМетод.
public ConcurrentDictionary <string,IMagickImage> ParallelImageComposer(Dictionary<string,MagickImage> InputImages, MagickImage InkZoneImage, int OrientationNumber)
{
var resultCollection = new ConcurrentDictionary <string,IMagickImage>();
Parallel.ForEach(InputImages, CurrentKeyValuePair =>
{
var img = new ImageComposer(InkZoneImage, CurrentKeyValuePair.Value, OrientationNumber).ComposedImage;
resultCollection.TryAdd(CurrentKeyValuePair.Key, img);
});
return resultCollection;
}