I want to double check with others whether this will be the right way to create an extension method that starts the asynchronous process and returns a function that, when called, essentially waits for this process and gets the result.
public static Func<R> HandleInvoke<T, R>(this Func<T, R> function, T arg, Action<IAsyncResult> callback)
{
IAsyncResult result = function.BeginInvoke(arg, new AsyncCallback(callback), function);
return delegate
{
return function.EndInvoke(result);
};
}
Essentially, I want to use it as a pseudo (pseudo-code):
Func<R> myFunc = (some delegate).HandleInvoke(arg, callback);
var result = myFunc();
Not sure if I need to worry about waiting in WaitHandles in this situation or not. Also not sure if you even need to make a callback. Also I think this is a closure?
EDIT
It ends with this
public static Func<R> HandleInvoke<T, R>(this Func<T, R> function, T arg)
{
IAsyncResult asyncResult = function.BeginInvoke(arg, iAsyncResult =>
{
if (!(iAsyncResult as AsyncResult).EndInvokeCalled)
{
(iAsyncResult.AsyncState as Func<T, R>).EndInvoke(iAsyncResult);
}
}, function);
return delegate
{
WaitHandle.WaitAll(new WaitHandle[] { asyncResult.AsyncWaitHandle });
return function.EndInvoke(asyncResult);
};
}
Which seems to work well. The callback checks if EndInvoke has been called, and if not, calls it. Otherwise, EndInvoke is called inside the returned delegate.
2ND EDIT
- , , . , .EndInvoke(), , EndInvoke R. Thread.Sleep(), , . , , R .
public static Func<R> HandleInvoke<T, R>(this Func<T, R> function, T arg)
{
R r = default(R);
IAsyncResult asyncResult = function.BeginInvoke(arg, result =>
{
r = (result.AsyncState as Func<T, R>).EndInvoke(result);
}, function);
return delegate
{
while (!(asyncResult as AsyncResult).EndInvokeCalled)
{
Thread.Sleep(1);
}
return r;
};
}