1

所以我对我的应用程序进行了多线程处理。我遇到了这个错误“跨线程操作无效:控制从创建它的线程以外的线程访问。”

我的线程正在调用 Windows 窗体控件。所以为了解决这个问题,我使用了

Control.Invoke(new MethodInvoker(delegate { ControlsAction; }));

我试图找出一种方法来制作这种通用方法,以便我可以重用代码并使应用程序更清洁。

例如,在我的调用中,我使用富文本框执行以下操作。

rtbOutput.Invoke(new MethodInvoker(delegate {    
rtbOutput.AppendText(fields[0].TrimStart().TrimEnd().ToString() + " Profile not   
removed.  Check Logs.\n"); }));

另一个是带有一个组合框,我只是在其中设置文本。

cmbEmailProfile.Invoke(new MethodInvoker(delegate { EmailProfileNameToSetForUsers = 
cmbEmailProfile.Text; }));

另一个例子是一个富文本框,我只是简单地清除它。

 rtbOutput.Invoke(new MethodInvoker(delegate { rtbOutput.Clear(); }));

我将如何创建一个可以为我执行此操作的通用函数,我只需要通过我希望它执行的操作来传递控件?

这是我们迄今为止提出的。

private void methodInvoker(Control sender, Action act)
    {
        sender.Invoke(new MethodInvoker(act));
    }

所以问题类似于 appendtext,它似乎不喜欢。

4

1 回答 1

3

这样的事情应该可以解决问题:

public static class FormsExt
{
    public static void InvokeOnMainThread(this System.Windows.Forms.Control control, Action act)
    {
        control.Invoke(new MethodInvoker(act), null);
    }
}

然后使用它很简单:

        var lbl = new System.Windows.Forms.Label();
        lbl.InvokeOnMainThread(() =>
            {
               // Code to run on main thread here
            });

使用您的原始标签:

        rtbOutput.InvokeOnMainThread(() =>
            {
               // Code to run on main thread here
               rtbOutput.AppendText(fields[0].TrimStart().TrimEnd().ToString() + " Profile not removed.  Check Logs.\n"); }));
            });
于 2013-04-05T15:09:11.067 回答