如果您的界面要求您返回一个任务,那么您最终可能会不必要地在线程池上安排工作,只是为了进行 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);
}
调用者将调用结果来启动操作(即调用 FromAsync/BeginSend)并使用 ContinueWith() 来处理结果:
Func<Task<int>> sendAsync = socket.SendAsync(buffer, offset, count);
sendAsync().ContinueWith(
antecedent => Console.WriteLine("Sent " + antecedent.Result + " bytes."));
如果在你的界面中暴露 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));
}
调用者看起来像:
DelayedTask<int> task = socket.SendAsync(buffer, offset, count);
task.Start().ContinueWith(
antecedent => Console.WriteLine("Sent " + antecedent.Result + " bytes."));