15

私は次の署名を持つ非同期メソッドを持っています:

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

しかし、次のエラーが発生します。

引数1:「メソッドグループ」から「System.Func」に変換できません

適切なオーバーロードされたFromAsyncメソッドhttp://msdn.microsoft.com/en-us/library/system.threading.tasks.taskfactory.fromasync.aspxはないようです。これは、最大5つの引数(コールバックと状態を含む)のみをサポートします。 BeginXXXメソッドで。

BeginXXXメソッドをリファクタリングして6つの引数ではなくオブジェクトを取得する以外に、FromAsyncを使用してオブジェクトを実行する方法はありますか?

4

3 に答える 3

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

この手法(部分関数アプリケーション)は、任意の数の入力パラメーターを持つbeginメソッドで機能します。

于 2014-07-02T15:49:48.370 に答える
7

実際、Factory.FromAsync(のオーバーロードされたメソッドを使用できるようです。これは、最初の引数としてIAsyncResultオブジェクトを取り、2番目の引数としてコールバックメソッドを取ります。

result = Task<string>.Factory.FromAsync(
                instance.BeginGetMyNumber("foo", "bar", "bat", 1, null, null),
                instance.EndGetMyNumber);
于 2013-03-24T22:48:10.183 に答える
5

ええ、基本的に、あなたは議論を使い果たしました。:(

このFromAsyncメソッドは、最大3つの非同期呼び出し引数のみを取り、次のように完全にスペルアウトされます。

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

しかし、あなたがたは1つ多すぎます。

ああ、助けになるかもしれない何かを手に入れました-あなたはこれをきれいにしたいでしょう、これは非常に一緒に投げられます!!!

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;
    } 
}
于 2013-03-23T02:08:47.803 に答える