s d*_*s d 15 c# asynchronous iasyncresult
我有一个带有以下签名的异步方法:
IAsyncResult BeginGetMyNumber(string foo, string bar, string bat, int bam, AsyncCallback callback, object state)
Run Code Online (Sandbox Code Playgroud)
我想使用Factory.FromAsync执行它,如下所示:
var result = Task<int>.Factory.FromAsync(
instance.BeginGetMyNumber,
instance.EndGetMyNumber,
"foo",
"bar",
"bat",
100, /*bam*/
null);
Run Code Online (Sandbox Code Playgroud)
但是我收到以下错误:
参数1:无法从'方法组'转换为'System.Func'
似乎没有合适的重载FromAsync方法http://msdn.microsoft.com/en-us/library/system.threading.tasks.taskfactory.fromasync.aspx,它只支持最多5个参数(包括回调和状态)在BeginXXX方法上.
除了重构BeginXXX方法以获取对象而不是六个参数之外,有没有办法使用FromAsync执行它?
小智 9
result = Task<string>.Factory.FromAsync(
(callback, state) => instance.BeginGetMyNumber("foo", "bar", "bat", 1, callback, state),
instance.EndGetMyNumber, state: null);
Run Code Online (Sandbox Code Playgroud)
此技术(部分函数应用程序)适用于具有任意数量输入参数的begin方法.
实际上我似乎可以使用Factory.FromAsync的重载方法(它将IAsyncResult对象作为第一个参数,将回调方法作为第二个参数:
result = Task<string>.Factory.FromAsync(
instance.BeginGetMyNumber("foo", "bar", "bat", 1, null, null),
instance.EndGetMyNumber);
Run Code Online (Sandbox Code Playgroud)
是的,基本上,你已经没有参数了.:(
该FromAsync方法最多只需要三个传递给异步调用的参数,完全拼写如下:
var result = Task<int>
.Factory
.FromAsync<string,string,string>(
BeginGetMyNumber,
EndGetMyNumber,
"foo",
"bar",
"bat",
null);
Run Code Online (Sandbox Code Playgroud)
如果你有:
IAsyncResult BeginGetMyNumber(
string foo,
string bar,
string bat,
AsyncCallback callback,
object state)
{
}
Run Code Online (Sandbox Code Playgroud)
但是你有一个太多了.
哦,有一些可能会有所帮助的东西 - 你会想要清理它,这是非常抛在一起!
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;
}
}
Run Code Online (Sandbox Code Playgroud)