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

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

7   голосов , оценка 4.571 из 5
Похожие ответы