2012-06-15 2 views
0

Цель:Cross вопрос потоковая обновления источника данных

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

BGWorker 1 отвечает за вызов DLL-метод для обхода сайта BGWorker 2 отвечает за обновление DataGridView, используя Datasource = источник сеттер

вопросы:

Мой длл получает в качестве аргумента , ссылка на источник данных, который будет заполнен во время работы .dll. В принципе, DLL собирается добавлять объект в источник данных раз в то время, пока он не завершится.

BGWorker 2 делает это:

while (1 == 1) // Runs until is it manually disposed 
{ 
    CoursesGrid.BeginInvoke // inline method 
    (
     (Action) delegate 
     { 
      if (_coursesSource.Count > 0) // if source is not empty,Binds. 
      { 
       try 
       { 
        CoursesGrid.DataSource = _coursesSource; 
        CoursesGrid.EndEdit(); 
       } 
       catch (Exception ex) 
       { 
        Logs.LogWriter.LogError(ex); 
       }     
      } 
      else 
      { 
       // Signals User To keep Waiting 
      } 
     } 
    ); 
Thread.Sleep(4000); 

Поведение потока:

  • Dll вызывается
  • Метод Разбирает элемент и добавляет к источнику
  • В конце концов, BGWorker 2 Пробуждает и связывает источник DataGridView с измененным источником
  • Dll нити продолжают разбор, но не только он пытается добавить новый элемент к источнику

TL: DR: тему 1 Записывает на источник Thread 2 Читает этот модифицированный источник, и связывает его с DataGridView к нему освежит тему 1 Не удается снова писать на источник:

"Cross-thread operation not valid: Control 'CoursesGrid' accessed from a thread other than the thread it was created on."} 

Обе нити обработки того же источника, но BGWorker 2, только связывает его с интерфейсом, это должно работать. Любая идея о том, что может произойти здесь?

+2

Я предполагаю, что что-то не работает так, как вы хотите, может быть, вы могли бы рассказать нам, что работает или не работает, и каковы ошибки. – CodingGorilla

+1

btw, fyi, В C# 3.0 вы можете написать только 'BeginInvoke (() => {...})' – abatishchev

+0

@CodingGorilla Отредактировано. Извините, если это было непонятно в первый раз. Добавлено TL: DR –

ответ

2

Я думаю, что происходит то, что вы привязываете сетку данных к вашему _coursesSource, что заставляет сетку данных отображать первую строку. Затем, позже, вы модифицируете тот же самый экземпляр_coursesSource, который, вероятно, вызывает уведомление об изменении свойства или изменении коллекции, которое заставляет сетку данных пытаться обновить себя (т. Е. Показать вновь добавленную строку).

Но так как модификация происходит в другом потоке, событие, которое сетка данных «слышит» и отвечает, также происходит на этой фоновой нити, которая вызывает нарушение поперечной нити.

Что вам нужно сделать, это либо) маршалировать надстройку к _coursesSource на поток пользовательского интерфейса (который он не звучит, как вы можете легко сделать), или б) связываются с копией _coursesSource, а затем в вашем BGWorker 2, каждый раз, когда вы обновляете _coursesSource, перевяжите сетку с новой копией, таким образом, сетка никогда не «слышит» уведомления об изменении, она всегда просто привязывается к новой копии коллекции. Это не самый эффективный способ сделать что-то, но он должен выполнить эту работу для вас.

+0

Просто попробовал второй подход. На BGWorker 2 я получаю ссылку на источник _coursesSource, скопирую его в «temp» BindingSource и привязывает GridView к «temp» BindingSource. Все еще есть та же проблема. Какой-нибудь другой подход, который вы могли бы подумать? –

+0

Можете ли вы обновить сообщение своим новым кодом и указать, где именно происходит исключение? – CodingGorilla

+0

Там вы: http://pastebin.com/TwAh0UtK Надеюсь, это поможет –

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