2013-03-23 30 views
14

Mam metodę transmisji asynchronicznej z następującym podpisem:Zbyt wiele argumentów w BeginXXX dla FromAsync?

IAsyncResult BeginGetMyNumber(string foo, string bar, string bat, int bam, AsyncCallback callback, object state) 

Chcę wykonać go za pomocą Factory.FromAsync tak:

var result = Task<int>.Factory.FromAsync(
       instance.BeginGetMyNumber, 
       instance.EndGetMyNumber, 
       "foo", 
       "bar", 
       "bat", 
       100, /*bam*/ 
       null); 

ale pojawia się następujący błąd:

Argument 1: cannot convert from 'method group' to 'System.Func'

Wygląda na to, że nie ma odpowiedniej przeciążonej metody FromAsync http://msdn.microsoft.com/en-us/library/system.threading.tasks.taskfactory.fromasync.aspx, obsługuje ona tylko do 5 argumentów (w tym wywołania zwrotnego i stanu) Metoda BeginXXX.

Inaczej niż refaktoryzacja metody BeginXXX w celu pobrania obiektu, a nie sześciu argumentów, czy istnieje sposób na wykonanie tego przy pomocy FromAsync?

Odpowiedz

7

Właściwie wydaje mogę używać przeciążonej metody Factory.FromAsync (który przyjmuje obiekt IAsyncResult jako pierwszy argument i metody wywołania zwrotnego jako drugi:

result = Task<string>.Factory.FromAsync(
       instance.BeginGetMyNumber("foo", "bar", "bat", 1, null, null), 
       instance.EndGetMyNumber); 
+4

Po tym przeciążeniu 'FromAsync' nie otrzyma szansy na przekazanie wywołania zwrotnego do metody' BeginGetMyNumber' - już przekazałeś wartość null. Zamiast tego to przeciążenie użyje 'IAsyncResult.WaitHandle' do powiadomienia, gdy operacja zostanie zakończona. Jest to mniej efektywne - więcej informacji można znaleźć na stronie http://blogs.msdn.com/b/pfxteam/archive/2012/02/06/10264610.aspx. – Daniel

+0

Działa dla czterech parametrów, ale mam pięć parametrów same nie działa dla mojego przypadku. Co powinienem zrobić ? –

3

Tak, w zasadzie zabrakło ci argumentów. :(

Sposób FromAsync zajmuje tylko maksymalnie trzy przeszły-do-asynchronicznym-call argumentów, orkisz w całości tak:

var result = Task<int> 
    .Factory 
    .FromAsync<string,string,string>(
     BeginGetMyNumber, 
     EndGetMyNumber, 
     "foo", 
     "bar", 
     "bat", 
     null); 

Który będzie działać, jeśli miał:

.
IAsyncResult BeginGetMyNumber(
    string foo, 
    string bar, 
    string bat, 
    AsyncCallback callback, 
    object state) 
{ 
} 

Ale ye've dostał jeden zbyt wiele

Ooh, coś, co może pomóc - Będziemy chcieli, aby to posprzątać, jest to niezwykle rzucony together !!!

public static class Ext 
{ 
    public static Task<TResult> FromAsync<TArg1, TArg2, TArg3, TArg4, TResult>(
     this TaskFactory<TResult> factory, 
     Func<TArg1,TArg2,TArg3,TArg4,AsyncCallback, object, IAsyncResult> beginMethod, 
     Func<IAsyncResult, TResult> endMethod, 
     TArg1 arg1, 
     TArg2 arg2, 
     TArg3 arg3, 
     TArg4 arg4, 
     object state, 
     TaskCreationOptions creationOptions = TaskCreationOptions.None, 
     TaskScheduler scheduler = null) 
    { 
     scheduler = scheduler ?? TaskScheduler.Current; 
     AsyncCallback callback = null; 
     if (beginMethod == null) 
     { 
      throw new ArgumentNullException("beginMethod"); 
     } 
     if (endMethod == null) 
     { 
      throw new ArgumentNullException("endMethod"); 
     } 
     TaskCompletionSource<TResult> tcs = 
      new TaskCompletionSource<TResult>(state, creationOptions); 
     try 
     { 
      if (callback == null) 
      { 
       callback = delegate (IAsyncResult iar) 
       { 
        tcs.TrySetResult(endMethod(iar)); 
       }; 
      } 
      beginMethod(arg1, arg2, arg3, arg4, callback, state); 
     } 
     catch 
     { 
      tcs.TrySetResult(default(TResult)); 
      throw; 
     } 
     return tcs.Task; 
    } 
} 
+0

To całkiem fajne - ale wygląda na to, że mogę użyć innej przeciążonej metody –

8
result = Task<string>.Factory.FromAsync(
    (callback, state) => instance.BeginGetMyNumber("foo", "bar", "bat", 1, callback, state), 
    instance.EndGetMyNumber); 

ten technika (zastosowanie funkcji częściowej) działa dla metod początkowych z dowolną liczbą parametrów wejściowych

+0

to przeciążenie FromAsync wymaga stanu jako trzeciego parametru. Poza tym to dla mnie zadziałało. – Royston46

+0

Działa jak urok. OP powinien przyjąć tę odpowiedź samodzielnie. –

+1

Cóż, został opublikowany ponad rok po tym, jak już zaakceptowałem moją własną odpowiedź. Cholera, entropia! –

Powiązane problemy