2011-02-18 81 views
5

我正在實現一個需要實現BeginDoSomethingEndDoSomething方法的接口。然而我的DoSomething並不是很長時間。 爲簡單起見假設DoSomething只比較兩個變量,並返回是否A> B如何創建立即完成的IAsyncResult?

所以我BeginDoSomething應該是這樣的:

protected override IAsyncResult BeginDoSomething(int a, int b, AsyncCallback callback, object state) 
{ 
    bool returnValue = a > b; 
    return ...; //what should I return here? 
    //The method actually already completed and I don't need to wait for anything 
} 

我不知道我應該返回什麼。我只實現了BeginDoSomething,因爲我必須這樣做,而不是因爲我的方法長時間運行。我是否需要實施我自己的IAsyncResult? .NET庫中是否有實現?

回答

3

快速黑客:

public class MyAsyncResult : IAsyncResult 
    { 
     bool _result; 

     public MyAsyncResult(bool result) 
     { 
      _result = result; 
     } 

     public bool IsCompleted 
     { 
      get { return true; } 
     } 

     public WaitHandle AsyncWaitHandle 
     { 
      get { throw new NotImplementedException(); } 
     } 

     public object AsyncState 
     { 
      get { return _result; } 
     } 

     public bool CompletedSynchronously 
     { 
      get { return true; } 
     } 
    } 

然後在你的BeginDoSomething像這樣使用它這樣做的方法是使用代理:

protected override IAsyncResult BeginDoSomething(int a, int b, AsyncCallback callback, object state) 
{ 
    bool returnValue = a > b; 
    Func<int,int,bool> func = (x,y) => x > y; 
    return func.BeginInvoke(a,b,callback,state); 
} 

這種方法的缺點是,如果兩個線程同時調用此方法,則需要小心,否則會發生錯誤。

5

這是一個有點快速和骯髒的,但你可以實現一個實現IAsyncResult的,像這樣一類:

return new MyAsyncResult(a > b); 
+2

我認爲`AsyncWaitHandle`屬性應該返回對* set *`ManualResetEvent`(或類似的)的引用。客戶嘗試等待句柄是完全合理的,並且不應該引發異常。 – Ani 2011-02-18 04:16:05

+0

的確,我們可以做到這一點,但作爲一個WaitHandle是一個昂貴的對象,創建一個看起來很浪費,因爲它永遠不會**相關。 – 2011-02-18 04:26:42