作者:唐旭阳一一一滴泪15 | 来源:互联网 | 2024-11-09 11:54
本文探讨了在任务完成后将其转换为最终状态时的异常处理机制。通过分析`TaskCompletionSource`的使用场景,详细阐述了其在异步编程中的重要作用,并提供了具体的实现方法和注意事项,帮助开发者更好地理解和应用这一技术。
refs:
https://stackoverflow.com/questions/15316613/when-should-taskcompletionsourcet-be-used
https://technet.microsoft.com/zh-cn/library/dd449174(v=vs.110).aspx
https://code.msdn.microsoft.com/Windows-Phone-8-Networking-835239c1/sourcecode?fileId=70769&pathId=221052408
相关
https://hmemcpy.com/2013/01/turning-old-and-busted-asynchronous-code-into-new-asyncawait-enabled-hotness-with-taskcompletionsourcet/
An attempt was made to transition a task to a final state when it had already completed
TaskCompletionSource is used to create Task objects that don't execute code.
In Real World Scenarios TaskCompletionSource is ideal for I/O bound operations.
This way you get all the benefits of tasks (e.g. return values, continuations etc) without blocking a thread for the duration of the operation.
If your "function" is an IO bound operation it isn't recommended to block a thread using a new Task.
Instead using TaskCompletionSource you can create a slave task to just indicate when your I/O bound operation finishes or faults.
TaskCompletionSource 对于非task型方法,并且有事务需要处理,可返回task,并带上result或exception
如(only a event based api is available )
TaskCompletionSource completionSource;
public Task SendUsingManagedSocketsAsync(string strServerIP)
{
// enable asynchronous task completion
completiOnSource= new TaskCompletionSource();
// create a new socket
var socket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
// create endpoint
var ipAddress = IPAddress.Parse(strServerIP);
var endpoint = new IPEndPoint(ipAddress, PORT);
// create event args
var args = new SocketAsyncEventArgs();
args.RemoteEndPoint = endpoint;
args.Completed += SocketConnectCompleted;
// check if the completed event will be raised. If not, invoke the handler manually.
if (!socket.ConnectAsync(args))
SocketConnectCompleted(args.ConnectSocket, args);
return completionSource.Task;
}
private void SocketConnectCompleted(object sender, SocketAsyncEventArgs e)
{
// check for errors
if (e.SocketError != System.Net.Sockets.SocketError.Success)
{
completionSource.SetException(new Exception("Failed with " + e.SocketError));
// do some resource cleanup
CleanUp(e);
return;
} else
{
completionSource.SetResult(null);
}
// check what has been executed
switch (e.LastOperation)
{
case SocketAsyncOperation.Connect:
HandleConnect(e);
break;
case SocketAsyncOperation.Send:
HandleSend(e);
break;
}
}