2013-10-03 26 views
5

對於通過「out」參數返回多個值的end方法,如何使用Task.Factory.FromAsync工廠?End Method中帶「out」參數的Task.Factory.FromAsync

Begin方法有此簽名:

public virtual System.IAsyncResult BeginGetCaseStatus(int CaseOID, int ClientOID, System.AsyncCallback @__Callback, object @__UserData) 

End方法是:

public virtual void EndGetCaseStatus(System.IAsyncResult @__AsyncResult, out DTGenericCode[] BasicStatus, out DTGenericCode[] ARStatus) 

我可以一些如何使用:

public Task<?> GetCaseStatusAsync(int CaseOID, int ClientOID) 
{ 
    return Task.Factory.FromAsync (BeginGetCaseStatus(CaseOID, ClientOID, null, null), EndGetCaseStatus(?, ?)); 
} 
+1

這不是標準的APM End ***調用,所以FromAsync方法將不起作用。 –

回答

6

沒有FromAsync超載,將工作爲了這。最好的辦法很可能會建立自己的包裝:

public class ResultStatus 
{ 
    public ResultStatus(DTGenericCode[] basicStatus, DTGenericCode[] arStatus) 
    { 
     this.BasicStatus = basicStatus; 
     this.ARStatus = arStatus; 
    } 
    public DTGenericCode[] BasicStatus { get; private set; } 
    public DTGenericCode[] ARStatus { get; private set; } 
} 

public Task<ResultStatus> GetCaseStatusAsync(int CaseOID, int ClientOID) 
{ 
    var tcs = new TaskCompletionSource<ResultStatus>(); 
    theClass.BeginGetCaseStatus(CaseOID, ClientOID, iar => 
      { 
       DTGenericCode[] bs; 
       DTGenericCode[] as; 
       theClass.EndGetCaseStatus(iar, out bs, out as); 

       tcs.SetResult(new ResultStatus(bs, as)); 
      }, null); 

    return tcs.Task; 
} 
+1

問題是,如果'theClass.EndGetCaseStatus'引發一個異常,你是否需要用try-catch來包裝它,並將異常傳遞給'tcs.SetException('? –

+1

@ScottChamberlain是的,如果有一種方法可以取消,也應該設置取消標誌('tcs.SetCancelled()')。儘管如此,這是最簡單的包裝方法。 –

+0

「沒有'FromAsync'重載可以用於此目的。」你可以通過一點努力使其工作(參見我的答案)。 – svick

5

FromAsync()endMethod參數是一個委託,所以你可以使用lambda到out - 形式轉換成的-End方法的正常形態。喜歡的東西:

private static Task<Tuple<DTGenericCode[], DTGenericCode[]>> GetCaseStatusAsync(
    int CaseOID, int ClientOID) 
{ 
    return Task.Factory.FromAsync(
     BeginGetCaseStatus, ar => 
     { 
      DTGenericCode[] basicStatus; 
      DTGenericCode[] arStatus; 

      EndGetCaseStatus(ar, out basicStatus, out arStatus); 

      return Tuple.Create(basicStatus, arStatus); 
     }, 
     CaseOID, ClientOID, null); 
} 

雖然你可能需要使用自定義類型,而不是Tuple