har*_*men 4 .net task-parallel-library
我有一个返回任务的方法,如:
public static Task<int> SendAsync(this Socket socket, byte[] buffer, int offset, int count)
{
if (socket == null) throw new ArgumentNullException("socket");
if (buffer == null) throw new ArgumentNullException("buffer");
return Task.Factory.FromAsync<int>(
socket.BeginSend(buffer, offset, count, SocketFlags.None, null, socket),
socket.EndSend);
}
Run Code Online (Sandbox Code Playgroud)
我想保留对该任务的引用并稍后运行它.但是,似乎由FromAsync方法创建的任务立即执行.我怎样才能推迟执行?
小智 5
如果你的接口要求你返回一个任务,你可能最终不必要地调度线程池上的工作只是为了进行BeginSend()调用(这是前一个答案中发生的事情,其中FromAsync()调用被另一个任务包装).
相反,如果您能够更改界面,则可以使用标准的延迟执行技术,例如:
public static Func<Task<int>> SendAsync(this Socket socket, byte[] buffer, int offset, int count)
{
if (socket == null) throw new ArgumentNullException("socket");
if (buffer == null) throw new ArgumentNullException("buffer");
return () =>
Task.Factory.FromAsync<int>(
socket.BeginSend(buffer, offset, count, SocketFlags.None, null, socket),
socket.EndSend);
}
Run Code Online (Sandbox Code Playgroud)
调用者将调用结果来启动操作(即调用FromAsync/BeginSend)并使用ContinueWith()来处理结果:
Func<Task<int>> sendAsync = socket.SendAsync(buffer, offset, count);
sendAsync().ContinueWith(
antecedent => Console.WriteLine("Sent " + antecedent.Result + " bytes."));
Run Code Online (Sandbox Code Playgroud)
如果在您的界面中暴露Func <>是不合适的,您可以将它包装到一个单独的类中:
public class DelayedTask<TResult>
{
private readonly Func<Task<TResult>> func;
public DelayedTask(Func<Task<TResult>> func)
{
this.func = func;
}
public Task<TResult> Start()
{
return this.func();
}
}
public static DelayedTask<int> SendAsync(this Socket socket, byte[] buffer, int offset, int count)
{
if (socket == null) throw new ArgumentNullException("socket");
if (buffer == null) throw new ArgumentNullException("buffer");
return new DelayedTask<int>(() =>
Task.Factory.FromAsync<int>(
socket.BeginSend(buffer, offset, count, SocketFlags.None, null, socket),
socket.EndSend));
}
Run Code Online (Sandbox Code Playgroud)
调用者看起来像:
DelayedTask<int> task = socket.SendAsync(buffer, offset, count);
task.Start().ContinueWith(
antecedent => Console.WriteLine("Sent " + antecedent.Result + " bytes."));
Run Code Online (Sandbox Code Playgroud)