How to return T value from BeginInvoke?
Asked Answered
S

3

1

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.

Simony answered 9/1, 2012 at 13:59 Comment(9)
Wouldn't it be easier to call Invoke rather than BeginInvoke since your function is clearly synchronous?Excrescent
As David mentions; if you need to return the T, then using BeginInvoke is pointless; however, you could perhaps pass a callback - maybe an Action<T> that you invoke once the value is available...? or return a Task<T>Abomasum
this is a asynchronous class , I used the BeginInvoke method, why do you say that it's synchronous? thx for your reply.Simony
@MarcGravell seems that Action<T> don't support return value :)Simony
@user1118566 it doesn't need to; it is a callback, i.e. you start the Func<T> async, then invoke the Action<T> in the callback. However, the TPL is a much better option here...Abomasum
As David Heffernan points out, expecting a return value in the BeginInvokeExWithReturnValue makes your function synchronous again. Your code only gets the result in the EndInvoke function.Rochdale
@MarcGravell thx, But I am a little confused about what you said, could you pls help to give me a sample? I am not very familiar to Action indeed. and also , What's the TPLSimony
@Overflow thx for your notificationSimony
@user1118566 the TPL is the task parallelization library; part of 4.0; re "why do you say that it's synchronous" - if you have to wait for it to complete, to return the value then it is by definition, synchronous.Abomasum
A
6

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);
Abomasum answered 9/1, 2012 at 14:11 Comment(0)
E
0

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;
Edrei answered 9/1, 2012 at 14:7 Comment(1)
What's the exception? The whole point of the type parameter generic is to the caller tells the function what the expected return type is. If your 'iar' variable is not of type T, it will, of course, throw an exception. Verify that you're passing the right type in for the type returned by the async result.Edrei
R
0

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

Rochdale answered 9/1, 2012 at 14:18 Comment(2)
There's at least 4, then - a regular callback (non-APM, non-EAP) is also not uncommon.Abomasum
I think EAP will block the UI if we only throw the event out at the end of the function.Simony

© 2022 - 2024 — McMap. All rights reserved.