Обновление DataGrid из BackGroundWorker - PullRequest
0 голосов
/ 24 марта 2010

В моем приложении на C # есть рабочий фон и DataGrid. В работе моего Backgroundworker, который будет вызывать API в моих библиотеках, которые будут вводить некоторые данные в базу данных SQLite. После завершения моего вызова Api я сообщаю о прогрессе и в процессе моего фонового работника я получаю содержимое из базы данных и назначаю его в качестве источника данных для моей сетки. Я называю тот же API в том же фоновом режиме. В середине обработки мое приложение вылетает. Но если я не назначу источник данных в ProgressChanged, мое приложение не вылетает.

Ответы [ 3 ]

4 голосов
/ 24 марта 2010

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

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


 //In Form.Designer.cs

 Label myLabel = new Label();


 //In code behind under Background worker method
 LabelVlaueSetter SetLabelTextDel = SetLabelText; 
 if (myLabel .InvokeRequired)
 {

   myLabel.Invoke(SetLabelTextDel, "Some Value");
 }

 private delegate void LabelVlaueSetter(string value);

 //Set method invoked by background thread
 private void SetLabelText(string value)
 {
   myLabel.Text = value;
 }



2 голосов
/ 24 марта 2010

Как упоминает Джонатан Аллен, это не должно иметь значения. Если что-то еще не происходит. У меня было два случая, когда я не мог взаимодействовать с определенными элементами управления в событиях, генерируемых BackgroundWorker. Единственное, что сработало, это использование метода Invoke.

Попробуйте назначить DataSource в том же потоке, который создал элемент управления DataGridView. Вы делаете это с помощью метода Invoke элемента управления. Используйте следующий код. (Я не проверял, но это стандартная схема.)

Если это не сработает, попробуйте предложение Джонатана Аллена.

На самом деле, делайте те предложения, которые проще всего попробовать первыми.


    private delegate void SetDataSourceDelegate(object value);

    private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) {
        DataTable oData = null; //'assign data source
        if (dataGridView1.InvokeRequired) {
            dataGridView1.Invoke(new SetDataSourceDelegate(SetDataSource), new Object[] {oData});
        }else{
            SetDataSource(oData); 
        }
    }

    private void SetDataSource(object value) {
        dataGridView1.DataSource = value;
    }
1 голос
/ 24 марта 2010

Это не должно иметь значения, но почему вы используете ProgressChanged вместо RunWorkerCompleted?

Кроме того, попробуйте сделать все в потоке GUI без BackgroundWorker.Это позволит вам узнать, есть ли проблема в вашем коде или как ваш код взаимодействует с GUI.

...