2013-08-23 25 views
-4

填充的DataGridView我是新来的.NET。我需要在C#winforms中使用异步回调机制完成以下任务。使用异步回调的线程机制

在表单负载我需要从数据库中获取数据,并在一个DataGridView填充。检索可能需要很长时间,我想同时使用UI。另外我需要一个回调机制来检查datagridview是否被填充。我必须使用线程和异步回调机制来实现这一点。

private CustomerEntities cn = null; 

    delegate CustomerEntities DataSourceDelegate(); 
    delegate void loadGridViewDelegate(CustomerEntities dtCustomers); 

    DataSourceDelegate delegate_GetCustomers; 

    public CustomerEntities DataSource() 
    { 
     cn = new CustomerEntities(); 
     return cn; 
    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 
     status.Text = "Loading"; 
     delegate_GetCustomers = new DataSourceDelegate(DataSource); 
     delegate_GetCustomers.BeginInvoke(LoadCustomerCallBack, null); 
    } 

    private void LoadCustomerCallBack(IAsyncResult ar) 
    { 
     CustomerEntities dtCutomers; 
     dtCutomers = delegate_GetCustomers.EndInvoke(ar); 
     loadGridView(dtCutomers); 
    } 

    private void loadGridView(CustomerEntities dtCutomers) 
    { 
     if (dataGridView.InvokeRequired) 
     { 
      loadGridViewDelegate del = new loadGridViewDelegate(loadGridView); 
      dataGridView.Invoke(del, new CustomerEntities[] { dtCutomers }); 
     } 
     else 
     { 
      dataGridView.DataSource = dtCutomers.customerDetails; 
     } 
    } 

datagridview正在正确填充,但当我试图访问它时函数检索数据的UI被阻止。

+0

使用的BeginInvoke – Backtrack

+0

确定我们得到了你所需要的,但什么是你的问题? – I4V

+0

@ I4V:由于我是新来的.NET,我需要参与实现这一 – impulse

回答

0

您需要执行的是修改主线程上WinForm控件的任何代码。在回调使用这种类型的模式:

private void CallbackHandler (object sender, EventArgs e) 
{ 
    if (InvokeRequired) 
    { 
     Invoke((MethodInvoker)delegate { CallbackHandler (sender, e); }); 
     return; 
    } 

    // If you get here, you are running on the main thread. 
} 

编辑:至于实际的异步“获取数据”数据库库很可能有一个不接受回调作为它的一个参数的函数。这将为您处理所有其他事情。

处理由手工穿线简单地做一个任务:

Task.Factory.StartNew (() => 
{ 
    FunctionThatTakesALongTime(); 
    CallbackHandler(); 
} 
0

像这样:

myWindow.BeginInvoke(new My_Main.ProductDelegate(myWindow.PopulateGrid), new object[] { row }); 

然而,你应该只使用调用/ BeginInvoke的,如果你的代码是在后台线程上运行。

如果您UpdateProducts方法在UI线程上运行,你并不需要的BeginInvoke;你可以简单地正常调用该方法,像这样:

myWindow.PopulateGrid(row); 

如果你调用BeginInvoke,你需要通过移动循环内行的申报创建在每次迭代中一个单独的数组实例。