.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();
}
}
}