2011-01-10 3 views
0

У меня есть следующий код, в котором я пытаюсь обрабатывать большой объем данных и обновлять пользовательский интерфейс. Я пробовал то же самое, используя фона рабочего, но я получаю аналогичную проблему. Проблема заключается в том, что я пытаюсь использовать класс, который не был создан в новом потоке (фактическая ошибка заключается в том, что текущий поток не «владеет» экземпляром). Мой вопрос в том, есть ли способ передать этот экземпляр между потоками, чтобы избежать этой ошибки?Передача данных между потоками

DataInterfaceClass dataInterfaceClass = new DataInterfaceClass(); 

private void OutputData(List<MyResult> Data) 
{    
    progressBar1.Maximum = Data.Count; 
    progressBar1.Minimum = 1; 
    progressBar1.Value = 1; 

    foreach (MyResult res in Data) 
    {      
     // Add data to listview 
     UpdateStatus("Processing", res.Name); 

     foreach (KeyValuePair<int, string> dets in res.Details) 
     { 
      ThreadPool.QueueUserWorkItem((o) => 
      { 
       // Get large amount of data from DB based on key 
       // – gives error because DataInterfaceClass was 
       // created in different thread. 
       MyResult tmpResult = dataInterfaceClass 
        .GetInfo(dets.DataKey); 

       if (tmpResult == null) 
       { 
        // Updates listview 
        UpdateStatus("Could not get details", 
         dets.DataKey); 
       } 
       else 
       { 
        UpdateStatus("Got Details", dets.DataKey); 
       } 

       progressBar1.Dispatcher.BeginInvoke(
        (Action)(() => progressBar1.Value++)); 
      }); 
     } 
    } 
} 

EDIT:

DataInterfaceClass фактически definated и создается вне функции, она используется в, но это экземпляр и не статична.

ответ

1

UPDATE: Вы, кажется, изменили размещенную исходный код, так что ...

Вы должны создать экземпляр DataInterfaceClass исключительно для каждого фонового потока или задачи. Предоставьте вашей задаче достаточно ввода для создания собственного экземпляра.

Если вы пытаетесь получить доступ к данным в одной базе данных в строго параллельном режиме, это может привести к таймаутам базы данных. Даже если вы можете получить доступ к данным для работы многопоточным способом, я бы рекомендовал ограничить количество одновременных фоновых задач, чтобы это не происходило.

Вы можете использовать Semaphore (или аналогичный), чтобы гарантировать, что одновременно выполняется не более определенного количества задач.

+0

Я обновил вопрос, поскольку он появился, поскольку DataInterfaceClass был статичным - это не так. Что касается количества одновременных задач, цель этого заключается в простом обновлении пользовательского интерфейса при его запуске (так что я не ожидаю, что доступ к данным будет одновременно синхронным). –

+0

@ pm_2: Если вы не хотите одновременного доступа, вы должны поместить оба цикла foreach в один рабочий элемент, а не в очередь на работу внутри внутри вложенного цикла. – Thorarin

0

Создайте глобальный экземпляр для DataInterfaceClass внутри класса, который имеет метод OutputData, таким образом вы сможете использовать его в методе.

Однако вам необходимо быть осторожным при использовании. Если все потоки будут использовать один и тот же экземпляр для чтения из базы данных, это приведет к ошибкам.

Вы должны либо создать новый экземпляр DataInterfaceClass в каждом потоке, либо выполнить блокировку внутри вашего метода , чтобы избежать проблем с множественным доступом.

Смежные вопросы