2013-10-03 9 views
5

Jak używać fabryki Task.Factory.FromAsync dla metody zakończenia, która zwraca wiele wartości za pomocą parametrów "out"?Task.Factory.FromAsync z parametrami "out" w metodzie końcowej

miejsce rozpoczęcie metoda ma ten podpis:

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

metoda końcu jest:

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

mogę trochę jak zastosowanie:

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

To nie jest standardowe wywołanie APM End ***, więc metody FromAsync nie będą działać. –

Odpowiedz

6

Nie ma FromAsync przeciążenie, które pracują dla tego. Najlepszym rozwiązaniem będzie prawdopodobnie budować własne opakowanie:

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

Pytanie, czy 'theClass.EndGetCaseStatus' zgłasza wyjątek, należy go opakować przy użyciu funkcji catch-catch i przekazać wyjątek do' tcs.SetException ('? –

+1

@ScottChamberlain Tak, i jeśli istnieje sposób, aby anulować, powinien również ustawić flagę anulowania ('tcs.SetCancelled()') .Jest to jednak najprostszy z możliwych wrapperów, aby przekonać się o tym. –

+0

"Nie ma przeciążenia' FromAsync', które działałoby w tym celu. "Nie bezpośrednio, ale możesz sprawić, by działało to przy odrobinie wysiłku (zobacz moją odpowiedź). – svick

5

Parametrem FromAsync()endMethod jest delegatem, więc można użyć lambda do konwersji out postać a do normalnej postaci -End metod. Coś jak:

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); 
} 

Choć prawdopodobnie chcesz użyć niestandardowego typu zamiast Tuple.