代码之家  ›  专栏  ›  技术社区  ›  subbu

从BackgroundWorker更新DataGrid

  •  0
  • subbu  · 技术社区  · 16 年前

    我的C应用程序中有一个后台工作程序和一个数据报。在后台工作人员的do work中,它将调用我的DLL中的API,该API将在sqlite数据库中输入一些数据。在我的API调用完成后,我报告了我的BackgroundWorker的一个进度和进行中的事件,我从DB获取内容,并将其作为数据源分配给我的网格。我在同一个后台工作人员中调用相同的API。在处理应用程序崩溃的过程中。但是如果我不在progresschanged中分配数据源,我的应用程序不会崩溃。

    3 回复  |  直到 16 年前
        1
  •  4
  •   RockWorld    16 年前

    我假设您必须使用invoke方法访问UI对象。

    如果不尝试使用以下方法(在拥有控件的基础窗口句柄的线程上使用指定的参数列表执行指定的委托):

    
     //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
  •  2
  •   AMissico    16 年前

    正如约翰森·艾伦所说,这不重要。除非有别的事情发生。我有两种情况,我无法与由 BackgroundWorker . 唯一有效的方法是使用 Invoke 方法。

    尝试分配 DataSource 在创建 DataGridView 控制。你通过控制室 援引 方法。使用以下代码。(我没有测试,但这是标准模式。)

    如果这不起作用,那就试试乔纳森·艾伦的建议。

    实际上,先做最容易尝试的建议。


        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;
        }
    
        3
  •  1
  •   Jonathan Allen    16 年前

    这不重要,但为什么要使用ProgressChanged而不是RunWorkerCompleted?

    另外,尝试在没有后台工作人员的情况下在GUI线程上执行所有操作。这将让您知道代码中是否存在问题,或者代码如何与GUI交互。

    推荐文章