Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Task.Factory.FromAsync with "out" parameters in End Method

Tags:

c#

async-await

How do I use the Task.Factory.FromAsync factory for an end method that returns multiple values via "out" parameters?

The begin method has this signature:

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

End method is:

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

Can I some how use:

public Task<?> GetCaseStatusAsync(int CaseOID, int ClientOID)
{
    return Task.Factory.FromAsync  (BeginGetCaseStatus(CaseOID, ClientOID, null, null), EndGetCaseStatus(?, ?));
}
like image 244
user1231595 Avatar asked Oct 03 '13 23:10

user1231595


2 Answers

There is no FromAsync overload that would work for this. The best option would likely be to build your own wrapper:

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;
}
like image 160
Reed Copsey Avatar answered Sep 27 '22 21:09

Reed Copsey


The endMethod parameter of FromAsync() is a delegate, so you can use a lambda to convert the out-form to the normal form of -End methods. Something like:

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

Though you probably want to use a custom type instead of the Tuple.

like image 29
svick Avatar answered Sep 27 '22 19:09

svick