如何从C#中的UI线程运行代码

Sou*_*ver 0 c# multithreading winforms

有没有一种方法可以在UI线程外部调用代码时运行代码?我知道它基本上需要使用control.Invokecontrol.BeginInvoke。我的问题是我无法使用这些方法访问UI元素。

我的情况是这样的:

  1. UI-将DataTable设置为DataSource的DataGridView
  2. 在MainForm UI外部编写的线程(BackgroundWorker),用于更新(添加行)上述DataTable

我的应用程序遇到了问题,因此我编写了一个仅包含上述元素的简单应用程序,以检查其工作原理(或者为什么不起作用),我发现:

  1. 当我在BackgroundWorker线程中更新DataTable时,DataGridview无法看到此消息(可能所有事件都是从其他线程触发的),即使调用DGV.Refresh()也无法正常工作(它会更新DGV,但有时DGV会损坏并显示一无所有或只有1行),仅通过调整大小,滚动等方式强制DGV刷新。强制DGV显示来自DataTable的数据
  2. 当我能够运行Invoke时,一切正常,仅此而已

但这只是一个简单的应用程序,我将所有内容都保存在一个文件中。在我的“其他线程”看不见UI代码的情况下,我可以使用更大的应用程序做什么?我是否必须以某种方式传递单个控件作为参数,才能访问该线程?还是有其他更好看的解决方案?

小智 6

您可以通过以下方式使用Application.OpenForms:

    public void DoSomething(string s)
    {
        var form = System.Windows.Forms.Application.OpenForms[0];
        if (form.InvokeRequired)
        {
            Action<string> m = DoSomething;
            form.Invoke(m, s);
            return;
        }

        //do something
    }
Run Code Online (Sandbox Code Playgroud)