C# ThreadPool, почему не работает .ToArray()/

306
08 февраля 2018, 14:18

Добрый вечер, не хочет работать ToArray(), да и вообще ни как не могу использовать результаты выполнения функции, которую я выполняю в пуле потоков. В дебагере видно, что массив globalOrder содержит элементы, но он их не отдает, ни с помощью .ToArray(), ни перечислением всех объектов, итоговый массив orders просто остается пустым. В чем причина, может кто сталкивался?

p.s. до того, как я поместил её в ThreadPool все работало.

Фрагмент кода:

          ProgressbarModal bar1 = new ProgressbarModal();
          var timeStart = DateTime.Now;
          List<Order> globalOrder = new List<Order>();
          if (obj == null)
          {
          ThreadPool.QueueUserWorkItem(test.GetOrders, globalOrder);
          }
          else if (obj is DateTime)
          {
          var param = new Tuple<DateTime, List<Order>>((DateTime)obj, globalOrder);
          ThreadPool.QueueUserWorkItem(test.GetOrders1, param);
          }
          else if (obj is DateTime[])
          {
          var param = new Tuple<DateTime[], List<Order>>((DateTime[])obj, globalOrder);
          ThreadPool.QueueUserWorkItem(test.GetOrders2, param);
          }
          else if(obj is Int32)
          {
          var param = new Tuple<Int32, List<Order>>((Int32)obj, globalOrder);
          ThreadPool.QueueUserWorkItem(test.GetOrders3, param);
          }
          else
          {
          return;
          }
          bar1.ShowDialog();
          // Вот тут проблема, на точке останова, я вижу, что globalOrder
          // содержит 3000+ объектов, но массив orders так и остается пустой
          Order[] orders = globalOrder.ToArray();
          ProgressbarModal bar = new ProgressbarModal();
          ThreadPool.QueueUserWorkItem(OrdersWorker.Insert, orders);
          bar.ShowDialog();
Answer 1

ThreadPool.QueueUserWorkItem() говорит о том, что метод должен быть выполнен в потоке пула. После этого вызова программа продолжает выполняться дальше. Это значит, что когда вы обращаетесь к списку globalOrder, он еще не успел заполниться. Вам нужно переосмыслить то, что вы делаете, и, возможно, дожидаться окончания работы функций GetOrders.

К тому же стоит использовать потокобезопасную коллекцию (например, ConcurrentBag<T>), иначе при записи из одного потока и при чтении из другого потока возможны ошибки и/или получение неконсистентных данных. В этом не будет необходимости в случае, если вы будете дожидаться окончания работы потока.

READ ALSO
Использование класса regex

Использование класса regex

ЗдравствуйтеСтолкнулся с проблемой при использовании класса Regex

272
Как получить culture в service?

Как получить culture в service?

Столкнулся с проблемой при написании сервисаКак в сервисе узнать culture? В WinForms и WPF все получается, а вот в сервисе даже ошибку не бьет, а выводит...

268
Генерация синхронных extensions с помощью Roslyn

Генерация синхронных extensions с помощью Roslyn

ПриветПредположим, есть какой-то интерфейс IInterface

273