控制' x'从创建它的线程以外的线程访问

时间:2018-06-18 09:22:30

标签: c# winforms thread-synchronization

winform应用程序,我有一个网格视图和数据源填充(在绑定函数上)委托开始调用sapareted线程,但是gridView DataSource无法从新线程获取生成的值,因为gridview是在主线程上创建的:< / p>

这里我调用新线程

    private void button_selectFile_Click(object sender, EventArgs e)
    {

        if (resultLoadingFile == DialogResult.OK)
        {
            filename = openFileDialog_logLoader.FileName;
            string name = System.IO.Path.GetFileName(filename);
            label_selectFileStatus.Text = name;

            readDelegate parseAndSplit = new readDelegate(ReadLogFileAndDrawTable);
            AsyncCallback cb = new AsyncCallback(doneReadFile);
            IAsyncResult ar = parseAndSplit.BeginInvoke(filename, cb, dataGridView_mainTable);
        }
    }

这里我称之为bind:

    private void doneReadFile(IAsyncResult ar)
    {
        Bind();
    }

这是Bind():

private void Bind(){
        TableLoadMgr.ItemsLoaded = TableModelListFiltered.Count();
        updateLoadedStatus();
        //The following line throw exception:
        dataGridView_mainTable.DataSource = TableModelListFiltered;
    }

enter image description here enter image description here 真实的问题是: 我如何在主线程上触发Bind(),因为回调函数在新的委托线程上触发。

说明:

  1. 重复的主题问题,我看到没有回答winform和约束
  2. 计时器不是选项
  3. 新用户触发器(此类按钮&#34;显示&#34;线程完成后)无法选择

1 个答案:

答案 0 :(得分:3)

您的AsyncResult将具有一个AsyncState,它包含对DataGridView的引用。因此,您可以使用该控件来检查Bind()是否需要上下文切换,如果是,则使用控件的Invoke来切换线程:

private void doneReadFile(IAsyncResult ar)
{
    var ctl = ar.AsyncState as System.Windows.Forms.Control; // the control
    if (ctl != null && ctl.InvokeRequired) { // is Invoke needed?
        // call this method again, but now on the UI thread.
        ctl.Invoke(new Action<IAsyncResult>(doneReadFile), ar);
    } else {
       Bind();
    }
}