2009-08-05 35 views
2

現在,我有一個窗口應用程序(C#),吐出長時間運行的報告。每份報告都會從UI中獲取一些信息來約束報告。當然,報表創建發生在後臺線程上,我需要正確調用各種控件來獲取選定索引和值等內容。但我不認爲我的代碼看起來不錯,並希望有更好的模式。因爲有這麼多要求的控制,我對於將返回各類型進行泛型委託:清理調用模式?

private delegate string StringDelegate(); 
private delegate int IntDelegate(); 

再往下,有這些代表的不同實例:

private StringDelegate GetYearSelectedItem = new StringDelegate(cmbYearAsync); 

YearAsync看起來是這樣的:

private string cmbYearAsync() { 
    return cmbYear.SelectedItem.ToString(); 
} 

最後,在代碼是在後臺線程,這是我得到的值:

cmbYear.Invoke(GetCmbYearSelectedItem); 

是否有更簡單的方法從單獨的線程獲取這些值?

回答

2

假設您想要使用線程化設計(也許您希望後臺線程在運行時向用戶界面報告部分結果?),如果您擁有C#3,那麼您肯定可以將它稍微整理一下。有些人發現的擴展方法是這樣有用:

public static class ControlExtensions 
{ 
    public static T Invoke<T>(this Control ctrl, Func<T> func) 
    { 
     if (ctrl.InvokeRequired) 
      return (T) ctrl.Invoke(func); 

     return func(); 
    } 
} 

以及檢查電話是否需要整理,這也使得委託參數類型安全。所以你可以寫:

string selected = comboBox1.Invoke(() => comboBox1.SelectedItem.ToString()); 

沒有必要預先聲明所有其他的東西。只需編寫您要編寫的通用代碼,但在該lambda模式中。

對於不需要返回值的操作,您可以編寫一個類似的擴展方法,它需要Action而不是Func<T>,並返回void

4

簡短的回答

不要做;-)

長的答案

收集報表參數從UI控件前面(或許在小班),並將其傳遞給在背景報告邊線

這消除了跨線程調用UI控件,和解耦用戶界面的報告參數