2013-04-05 92 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