Страницы

Поиск по вопросам

понедельник, 6 января 2020 г.

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

#c_sharp #массивы #многопоточность #list


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

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

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

          ProgressbarModal bar1 = new ProgressbarModal();

          var timeStart = DateTime.Now;
          List globalOrder = new List();

          if (obj == null)
          {
          ThreadPool.QueueUserWorkItem(test.GetOrders, globalOrder);
          }
          else if (obj is DateTime)
          {
          var param = new Tuple>((DateTime)obj, globalOrder);
          ThreadPool.QueueUserWorkItem(test.GetOrders1, param);
          }
          else if (obj is DateTime[])
          {
          var param = new Tuple>((DateTime[])obj, globalOrder);
          ThreadPool.QueueUserWorkItem(test.GetOrders2, param);
          }
          else if(obj is Int32)
          {
          var param = new Tuple>((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();

    


Ответы

Ответ 1



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

Комментариев нет:

Отправить комментарий