Too many arguments in BeginXXX for FromAsync?

后端 未结 3 1964
说谎
说谎 2021-02-13 05:12

I have an async method with the following signature:

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


        
相关标签:
3条回答
  • 2021-02-13 05:31
    result = Task<string>.Factory.FromAsync(
      (callback, state) => instance.BeginGetMyNumber("foo", "bar", "bat", 1, callback, state),
       instance.EndGetMyNumber, state: null);
    

    This technique (partial function application) works for begin methods with any number of input params.

    0 讨论(0)
  • 2021-02-13 05:49

    Yeah, basically, you've run out of arguments. :(

    The FromAsync method only takes a maximum of three passed-to-the-async-call arguments, spelled out in full like so:

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

    Which would work if you had:

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

    But ye've got one too many.

    Ooh, got something that might help - you WILL want to clean this up, this is extremely thrown-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 讨论(0)
  • 2021-02-13 05:50

    Actually it seems I can use the overloaded method for Factory.FromAsync( that takes an IAsyncResult object as the first argument and a callback method as the second:

    result = Task<string>.Factory.FromAsync(
                    instance.BeginGetMyNumber("foo", "bar", "bat", 1, null, null),
                    instance.EndGetMyNumber);
    
    0 讨论(0)
提交回复
热议问题