-->

How to return T value from BeginInvoke?

2019-04-16 13:58发布

问题:

I want to write a class to simplify the asynchronous programing, like string s = mylib.BeginInvoek(test,"1"); here is my code:

   public T BeginInvokeExWithReturnValue<T>(Func<T> actionFunction)
    {
        ExecWithReturnType<T> execWtihReturnValue = new ExecWithReturnType<T>(actionFunction);
        IAsyncResult iar = execWtihReturnValue.BeginInvoke(new AsyncCallback(EndInvokeExWithReturnValue<T>), execWtihReturnValue);
        // how to code here to return value
    }

    private void EndInvokeExWithReturnValue<T>(IAsyncResult iar)
    {
        ExecWithReturnType<T> execWtihReturnValue = (ExecWithReturnType<T>)iar.AsyncState;
        execWtihReturnValue.EndInvoke(iar);
    }

this BeginInvokeExWithReturnValue function has no input parameter, but returns a value, But I don't know how to return a value from BeginInvokeExWithReturnValue function. Anyone who know this, Could you pls help me ? thx very much.

回答1:

What you are trying to do right now is not async; if you want to return the T, just use:

return actionFunction();

It will be less overhead.

If you want async, and you are on 4.0, then the TPL may be a good option:

public Task<T> BeginInvokeExWithReturnValue<T>(Func<T> actionFunction)
{
    var task = new Task<T>(actionFunction);
    task.Start();
    return task;
}

Now the caller can use:

var task = BeginInvokeExWithReturnValue(() => Whatever());

and then when desired, check for completion, block (Wait) for completion, register continuations, etc. Or just:

var result = task.Result; // implicit wait
Console.WriteLine(result);

This allows you to seamlessly write async code. Or in C# 5.0, seamlessly write continuations:

var result = await task; // continuation - this is **not** a wait
Console.WriteLine(result);


回答2:

As David pointed out, the Invoke method is probably what you want, but if you're looking to write you're own variant, you just need to type cast the value to the generic (T, in your example) to satisfy your comment.

return (T) iar;


回答3:

Following from the comments,

There are 3 models of Asyncronous development in .NET

APM - (BeginXXX EndXXX) Which you are using here, when the long running task completes it calls back into your code in the EndXXX method

EAP - Event based. In this model, when the long running task completes, an event is raised to inform your code.

TPL - New in .NET 4, this is the 'Task' based version. it looks most like Syncronous programming to client code, using a fluent interface. Its calls back to your code using continueWith.

Hope this helps