2013-03-23 4 views
14

У меня есть метод асинхронной со следующей подписью:Слишком много аргументов в BeginXXX для FromAsync?

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

Я хочу, чтобы выполнить его, используя Factory.FromAsync как это:

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

, но я получаю следующее сообщение об ошибке:

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

Кажется, нет подходящего перегруженного метода FromAsync http://msdn.microsoft.com/en-us/library/system.threading.tasks.taskfactory.fromasync.aspx, он поддерживает только до 5 аргументов (включая обратный вызов и состояние) на Метод BeginXXX.

Помимо рефакторинга метода BeginXXX, чтобы взять объект, а не шесть аргументов, есть ли способ выполнить его с помощью FromAsync?

ответ

7

На самом деле, кажется, можно использовать перегруженный метод Factory.FromAsync (который принимает объект IAsyncResult в качестве первого аргумента и метод обратного вызова в качестве второго:

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

С этой перегрузкой «FromAsync» не получает возможность передать обратный вызов вашему методу «BeginGetMyNumber» - вы уже прошли null. Вместо этого эта перегрузка будет использовать 'IAsyncResult.WaitHandle' для уведомления о завершении операции. Это менее эффективно - подробнее см. Http://blogs.msdn.com/b/pfxteam/archive/2012/02/06/10264610.aspx. – Daniel

+0

Он работает для четырех параметров, но у меня есть пять параметров, которые не работают для моего случая. Что мне делать ? –

3

Да, в основном у вас закончились аргументы. :(

FromAsync Метод занимает максимум три прошедших-к-асинхронного-вызов аргументов, изложенный в полном объеме, так как:

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

Какое будет работать, если у вас:

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

Но ye've получил слишком много

Ooh, есть что-то, что может помочь - вы хотите, чтобы очистить это, это чрезвычайно брошенный-вместе !!!

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

Это довольно круто - но похоже, что я могу просто использовать другой перегруженный метод. –

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

В этом метод (приложение с частичной функцией) работает для начинающих методов с любым количеством входных параметров.

+0

Эта перегрузка FromAsync требует состояния как третьего параметра. Кроме того, это работало для меня. – Royston46

+0

Работаю как шарм. OP должен принять этот ответ самостоятельно. –

+1

Ну, это было опубликовано более года после того, как я уже принял свой собственный ответ. Проклятье, энтропия! –