【问题标题】:Populating datagridview using asynchronous callback and thread mechanism使用异步回调和线程机制填充 datagridview
【发布时间】:2013-08-23 05:56:01
【问题描述】:

我是 .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 被阻止。

【问题讨论】:

  • 好的,我们得到了您需要的东西,但您的问题是什么?
  • @I4V:由于我是 .NET 新手,因此我需要执行此操作所涉及的步骤
  • 您显然正在参加课程/课程,虽然 stackoverflow 是您所描述主题的重要知识来源,但它的目的是解决您的整个作业。最好的解决方案是自己尝试一些编码,然后当/如果您需要帮助时回来提出更具体的问题。

标签: c# winforms datagridview


【解决方案1】:

像这样:

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

但是,如果您的代码在后台线程上运行,您应该只使用 Invoke / BeginInvoke。

如果您的 UpdateProducts 方法在 UI 线程上运行,则不需要 BeginInvoke;您可以简单地正常调用该方法,如下所示:

myWindow.PopulateGrid(row);

如果确实调用了 BeginInvoke,则需要通过在循环内移动行的声明来在每次迭代中创建一个单独的数组实例。

【讨论】:

    【解决方案2】:

    您需要在主线程上执行任何修改 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();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-30
      相关资源
      最近更新 更多