2011-06-07 114 views
3

我有兩個線程的應用程序。其中一個(T1)是主要的GUI形式,另一個(T2)是循環中的函數。當T2獲取一些信息時必須用GUI的形式調用函數。 我不確定我是否做得對。beginInvoke,GUI和線程

T2調用函數FUNCTION,它以GUI的形式更新某些東西。

public void f() { 
     // controler.doSomething(); 
    } 


public void FUNCTION() { 

    MethodInvoker method = delegate { 
      f(); 
    }; 

    if (InvokeRequired) { 
     BeginInvoke(method); 
    } else { 
      f(); 
    } 
} 

但是現在我必須聲明兩個函數。它如何只使用一個功能?或者它是如何正確的。

回答

14

你可以通過調用調用自己在一個單獨的方法做到這一點:

public void Function() 
{ 
    if (this.InvokeRequired) 
    { 
     this.BeginInvoke(new Action(this.Function)); 
     return; 
    } 

    // controller.DoSomething();   
} 

編輯迴應評論:

如果你需要傳遞額外的參數,你可以做到這一點使用lambda表達式如下:

public void Function2(int someValue) 
{ 
    if (this.InvokeRequired) 
    { 
     this.BeginInvoke(new Action(() => this.Function2(someValue))); 
     return; 
    } 

    // controller.DoSomething(someValue);   
} 
+1

尼斯模式。如果您是從第二個線程調用的,則可以使用一個遞歸調用來調用自己。我認爲調用應該是同步完成的,所以來自第二個線程的調用(看起來是同步的;只是一個普通的方法調用)將以與從GUI線程調用相同的方式工作,在返回之前執行適當的任務。 – KeithS 2011-06-07 16:14:58

+0

有趣:我沒有看到它這樣做......它不會導致無限循環? – IAbstract 2011-06-07 16:15:26

+0

@nirmus:在大括號之後 - 我認爲目標是刪除第二個函數[「f()」] - 在這裏,它被放置在大括號後的主函數中。基本上,如果你需要調用,你自己調用,如果沒有,你可以做任何你想做的事情...... – 2011-06-07 16:16:13

3

看起來不錯。您可以將匿名代理更改爲一個更清潔的lambda。爲了擺脫F()方法聲明中,你可以內聯的代碼放到委託,那麼要麼調用委託作爲MethodInvoker或簡單地調用它,就象任何其它方法:

public void FUNCTION() { 

    MethodInvoker method =()=> controller.doSomething(); 

    if (InvokeRequired) { 
     BeginInvoke(method); 
    } else { 
      method(); 
    } 
} 
+0

這是很好的解決方案。我必須學習一些關於lambda函數的內容,因爲我看到它有一個有趣的可能性。感謝幫助。 – nirmus 2011-06-07 16:23:21