none
Привязка данных из параллельного потока RRS feed

  • Вопрос

  • Есть такая проблема

    Приложение продолжительное время собирает данные в таблицу DataSet-а. Все это происходит в отдельном потоке.

    В родительском потоке имеется форма в которую необходимо отображать данные и дополнительную информацию о ходе дела.

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

    Допустим, в классе рабочего потока есть свойство Progress, которое должно отображаться, например в textbox на форме.

    Возможна ли в этих случаях задействовать привязку?

    Создавать события обновления свойств класса в рабочем потоке, подписываться на них в оконном и через Control.Invoke() безопасно обновлять - все это выглядит как-то уныло.

    При этом, прямая привязка DataTable к DataGridView из разных потоков почему-то работает нормально, а привязка самодельного свойства к текстовому полю вызывает исключения.

    • Перемещено Tagore Bandlamudi 1 октября 2010 г. 21:33 MSDN Forums consolidation (От:Visual C#)
    6 августа 2010 г. 11:45

Ответы

  • >Создавать события обновления свойств класса в рабочем потоке, подписываться на них в оконном и через Control.Invoke() >безопасно обновлять - все это выглядит как-то уныло.

    Почему уныло?

    Следующий код поместите в "оконный" (главный) поток (в класс, где лежит контролл, параметр которого необходимо изменить) и вызывайте метод SetProgress из "рабочего" потока. Таким же образом  передавайте DataTable в "оконный" поток после сбора всех данных. И ничего унылого я не вижу; кода немного (можно и меньше сделать ;) ), и все потокобезопасно.

     

     delegate void ProgressHandler(Int32 Progress);
    
     private void SetProgress(Int32 Progress)
     {
      if (this.InvokeRequired)
      {
      this.Invoke(new ProgressHandler(SetProgress), new Object[ ] { Progress });
      }
      else
      {
      this.textBox1.Text = Progress.ToString( );
      }
     }
    
    Svyatoslav Pankratov чуть-чуть со ссылкой ошибся, т.к. о межпоточных вызовах рассказывается во второй части этой статьи: http://rsdn.ru/article/dotnet/CSThreading2.xml

     

    • Помечено в качестве ответа I.Vorontsov 18 августа 2010 г. 7:04
    7 августа 2010 г. 0:24

Все ответы

  • может можно как-то BackgroundWorker использовать ?

    у него там есть уведомления , вдруг подойдёт.

    6 августа 2010 г. 12:06
  • Немного не то что нужно.

    Вопрос в следующем: как потокобезопасно организовать привязку данных из одного потока к элементам управления в другом.

    6 августа 2010 г. 16:37
  • Возможно здесь есть ответы на Ваши вопросы.
    6 августа 2010 г. 22:33
  • >Создавать события обновления свойств класса в рабочем потоке, подписываться на них в оконном и через Control.Invoke() >безопасно обновлять - все это выглядит как-то уныло.

    Почему уныло?

    Следующий код поместите в "оконный" (главный) поток (в класс, где лежит контролл, параметр которого необходимо изменить) и вызывайте метод SetProgress из "рабочего" потока. Таким же образом  передавайте DataTable в "оконный" поток после сбора всех данных. И ничего унылого я не вижу; кода немного (можно и меньше сделать ;) ), и все потокобезопасно.

     

     delegate void ProgressHandler(Int32 Progress);
    
     private void SetProgress(Int32 Progress)
     {
      if (this.InvokeRequired)
      {
      this.Invoke(new ProgressHandler(SetProgress), new Object[ ] { Progress });
      }
      else
      {
      this.textBox1.Text = Progress.ToString( );
      }
     }
    
    Svyatoslav Pankratov чуть-чуть со ссылкой ошибся, т.к. о межпоточных вызовах рассказывается во второй части этой статьи: http://rsdn.ru/article/dotnet/CSThreading2.xml

     

    • Помечено в качестве ответа I.Vorontsov 18 августа 2010 г. 7:04
    7 августа 2010 г. 0:24
  • Svyatoslav Pankratov чуть-чуть со ссылкой ошибся, т.к. о межпоточных вызовах рассказывается во второй части этой статьи: http://rsdn.ru/article/dotnet/CSThreading2.xml
    Я всю статью имел ввиду целиком =)
    7 августа 2010 г. 7:14
  • ОК, как я понял, в WinForms привязка из параллельного потока невозможна вообще. Доступ к обернутым win32 компонентам не из создавшего потока всегда жестоко карается, а DataGridView работает только потому, что не имеет аналога в win32 и полностью работает на .Net.

    Вопрос такой - а в WPF как дела с привязкой данных из другого потока? Все те же invoke, или нет?

    11 августа 2010 г. 10:06
  • Помоему в WPF ещё хуже с этим (поток <-> UI). Можете тут почитать: http://msdn.microsoft.com/ru-ru/magazine/cc163328.aspx

    А привязки нигде нет.

    11 августа 2010 г. 12:38