2013-04-05 94 views
1

所以我有多线程我的应用程序。我遇到了这个错误“跨线程操作无效:从其创建的线程以外的线程访问控制。”创建一个MethodInvoker函数

我的线程正在调用一个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,它似乎并不喜欢。

+0

的动作上代替/与委托。 – 2013-04-05 15:09:42

回答

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"); })); 
      }); 
+0

好吧,以便采取行动。如果它包含文本或类似的东西呢?如果我通过它行事会有用吗? – user1158745 2013-04-05 15:21:13

+0

因此,如果我需要使用rtbOutput.AppendText(fields [0] .TrimStart()。TrimEnd()。ToString()+“Email Profile set。\ n”) – user1158745 2013-04-05 15:24:07

+0

@ user1158745它不会工作,可以将该行放在匿名函数中,但是如果您想要传递参数,那么修改扩展方法签名是一件简单的事情。 – Clint 2013-04-05 15:29:01