2011-06-16 37 views
0

我想在backgroundworker進程上做一些工作,並在工作完成時我要顯示一個模態對話框。我已經得到了一個簡單的Action委託很好的代碼,但希望能夠傳遞一個Func委託並獲得返回類型。 我至今是一個方法Compact Framework Func <T>問題

public void ShowDialogWhile(Action work) 
    { 
     _work = work; 
     _worker.RunWorkerAsync(); 
     this.CenterForm(); 
     this.ShowDialog(); 
    } 

一個形式。我想獲得下一個工作是什麼樣的東西

public TResult ShowDialogWhile<TResult>(Func<TResult> work) 
    { 
     _workWithReturn = work; 
     _worker.RunWorkerAsync(); 
     this.CenterForm(); 
     this.ShowDialog(); 

     return (TResult)Result; 
    } 

我沒有任何運氣,到目前爲止,因爲我一直在當宣佈我的工作類型_workWithReturn時摔倒

 Func<TResult> _workWithReturn; 

有沒有人有任何想法?

這裏是完整的代碼。

public partial class AsyncWaitDialog : Form, IAsyncDialog 
{ 
    BackgroundWorker _worker = new BackgroundWorker(); 
    Action _work; 
    Func<TResult> _workWithReturn; 
    public object Result { get; private set; } 


    public AsyncWaitDialog() 
    { 
     InitializeComponent(); 
     _worker.DoWork += HandleDoWorkEvent; 
     _worker.RunWorkerCompleted += HandleWorkerCompleted; 
    } 


    public void ShowDialogWhile(Action work) 
    { 
     _work = work; 
     _worker.RunWorkerAsync(); 
     this.CenterForm(); 
     this.ShowDialog(); 
    } 

    public TResult ShowDialogWhile<TResult>(Func<TResult> work) 
    { 
     _workWithReturn = work; 
     _worker.RunWorkerAsync(); 
     this.CenterForm(); 
     this.ShowDialog(); 

     return (TResult)Result; 
    } 


    private void HandleDoWorkEvent(object sender, EventArgs e) 
    { 
     try 
     { 
      if (_work != null) 
      { 
       _work(); 
      } 
      if (_workWithReturn != null) 
      { 
       Result = _workWithReturn(); 
      } 

     } 
     catch (Exception) 
     { 
      this.Close(); 
      throw; 
     } 
    } 

    private void HandleWorkerCompleted(object sender, EventArgs e) 
    { 
     this.Close(); 
    } 

} 
+0

你說你繼續「摔倒」 - 到底發生了什麼? – 2011-06-16 18:26:48

+0

我收到以下編譯錯誤:無法找到類型或命名空間名稱'TResult'(缺少使用指令或程序集引用嗎?) – Andrew 2011-06-16 18:31:20

+0

TResult定義在哪裏?它被定義爲什麼?你能展示那段代碼嗎? – 2011-06-16 18:31:32

回答

2

編譯時收到的錯誤與Compact框架無關,而是泛型的錯誤使用。正如其他人所說,類型TResult超出了你的課堂範圍,除非你在課堂上聲明它。

如果我看看你想達到的目標,我會說你可以通過保持所有類型的特定方法來獲得你想要的。

public partial class AsyncWaitDialog : Form, IAsyncDialog 
{ 
    ... 
    //Func<TResult> _workWithReturn; REMOVE THIS LINE 
    ... 

    //Change your function to be this: 
    public TResult ShowDialogWhile<TResult>(Func<TResult> work) 
    { 
     var result = default(TResult); 
     _work =() => 
     { 
      result = work(); 
     }; 
     _worker.RunWorkerAsync(); 
     this.CenterForm(); 
     this.ShowDialog(); 

     return result; 
    } 
} 

您現在正被匿名委託它調用你的函數和函數的返回進行「工作」是ShowDialogWhile功能的範圍內舉行:如下 進行更改。好的和簡單的伎倆。

只是拋出一個重構在那裏,你可以使用現有的方法來處理工人和對話的邏輯:

public TResult ShowDialogWhile<TResult>(Func<TResult> work) 
    { 
     var result = default(TResult); 
     ShowDialogWhile(() => 
     { 
      result = work(); 
     }); 
     return result; 
    } 
+0

謝謝馬克,這實際上給了我一些具體的繼續。我確實意識到TResult結果超出了範圍,但是確實試圖找到一種方法來完成這項工作,而不必讓整個類通用 – Andrew 2011-06-17 06:54:07

1

你有TResult的通用方法,但你也有一個使用類型的字段。如果在運行時需要該類型的字段,則將泛型定義從方法移到類中。

public partial class AsyncWaitDialog : Form, IAsyncDialog 
{ 
    ... 
    Func<TResult> _workWithReturn; //TRESULT IS NOT IN SCOPE 
    ... 

    public TResult ShowDialogWhile<TResult>(Func<TResult> work) 
    { 
     //TResult **IS** in scope here 
     _workWithReturn = work; 
     _worker.RunWorkerAsync(); 
     this.CenterForm(); 
     this.ShowDialog(); 

     return (TResult)Result; 
    } 


// possible solution, move the generic definition of TResult to the class definition 

public partial class AsyncWaitDialog<TResult> : Form, IAsyncDialog { ... } 
1

您的問題是TResult是在ShowDialogWhile方法定義一個通用的,但你申報你的_workWithReturn指出範圍。一種修復方法是將TResult作爲類聲明的一部分。

+0

這是否適用於表單? – Andrew 2011-06-16 18:41:48

+2

當然,爲什麼不呢。我想象中的視覺設計師可能會忽略它。不確定你想要完成什麼,可能會有更簡單的方法來做同樣的事情。 – asawyer 2011-06-16 19:44:33