.NET 4.x Parallel.Foreach изменение коллекции - C#
Формулировка задачи:
Если коллекция Dictionary<string,Class> dic;
Первый поток добавляет и удаляет элементы из коллекции используя Parallel.Foreach
Второй поток обходит коллекцию и выполняет действия внутри класса, не изменяя саму коллекцию.
Вопрос номер 1: что будет если Parallel.Foreach второго потока будет выполнятся, а в это время первый поток добавит/удалит элемент коллекции.
Вопрос номер 2: что будет если Parallel.Foreach второго потока будет выполнятся, при этом в данный момент будет выполняться какой-то метод к примеру 10 элемента коллекции, а в это время первый поток удалит этот элемент коллекции (перед удалением из коллекции вызывает Dispose класса)
Поток 1:
Второй поток:
lock (locker) { if (Added.Count > 0) { Parallel.ForEach(Added, o, line => { if (!Remover.Contains(line.Key)) Dic[line.Key] = new Class(line.Key, line.Value); }); Added.Clear(); } if (Remover.Count > 0) { Parallel.ForEach(Remover, o, line => { if (Dic.ContainsKey(line)) { Dic[line].Dispose(); Dic.Remove(line); } }); Remover.Clear(); } }
Parallel.ForEach(Dic, o, line => { var api = line.Value; var res = api.Worker(); if (res == 1) { lock (locker) { Remover.Add(line.Key); CM.Log(api.my, "Бот завершил свою работу"); } } if (res == 2) { lock (locker) { if(!Remover.Contains(line.Key)) Added[line.Key] = api.my.AuthKey; } } });
Суть в чем: нужно в режиме реального времени добавлять/удалять элементы из коллекции Dic, при чем второй поток должен всегда работать вне зависимости от того изменяется ли коллекция или нет
Решение задачи: «.NET 4.x Parallel.Foreach изменение коллекции»
textual
Листинг программы
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace ConsoleApplication39 { class Program { public static Dictionary<string, Api> Dic = new Dictionary<string, Api>(); public static List<string> Deleted = new List<string>(); public static readonly ParallelOptions o = new ParallelOptions(); public static void Remover(string id) { Deleted.Add(id); } public static void Adder(string id) { Dic[id] = new Api(id); } static void Main(string[] args) { o.MaxDegreeOfParallelism = 10; Task.Factory.StartNew(() => { while (true) { Task.Factory.StartNew(() => { if (Deleted.Count > 0) { foreach (var line in Deleted) { Dic[line].Dispose(); Dic.Remove(line); Console.WriteLine(); } Deleted.Clear(); } Thread.Sleep(1000); }).ContinueWith(task => { if (Dic.Count > 0) { //Тут работа с Parallel.ForEach() } }); }; }); } } public class Api : IDisposable { public Api(string id) { } public void Dispose() { throw new NotImplementedException(); } } }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д