For starters, if you look at the syntax, you'll realize that you're actually invoking the BeginSend
method yourself and causing it to return the IAsyncResult
for the first parameter of FromAsync. That's just one of the overloads of FromAsync though. If you look there's other overloads and the ones you're looking for are the ones that take Func<...>
instead. Unfortunately these overloads will also invoke the method right away on your behalf due to the fact that, under the covers, what's really happening is that FromAsync is just wrapping the APM invocation pattern using a TaskCompletionSource<TResult>
.
The only way I can actually see you being able to defer the execution is to actually wrap the FromAsync
work up in a parent task which you don't Start
yourself. For example:
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 new Task<int>(() =>
{
return Task.Factory.FromAsync<int>(
socket.BeginSend(buffer, offset, count, SocketFlags.None, null, socket),
socket.EndSend).Result;
}
}
Now a caller can get the task like so:
Task<int> task = SendAsync(...);
and until they call task.Start()
the work would not begin.