C# 多线程 04-使用任务平行库 05-将 EAP 模式转换为任务
🏷️ 《C# 多线程》
将 EAP 模式转换为任务
关于 基于事件的异步模式(Event-based Asynchronous Pattern,简称 EAP)的实现方法可以参照 C# 多线程 03-使用线程池 07-使用 BackgroundWorker 组件 。
可以使用 TaskCompletionSource
类型将 EAP 转换为 Task。
csharp
/// <summary>
/// 将 EAP 模式转换为任务
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
// 主要是使用 TaskCompletionSource 类型
// T 是异步处理返回结果类型
var tcs = new TaskCompletionSource<int>();
var worker = new BackgroundWorker();
worker.DoWork += (sender, eventArgs) =>
{
eventArgs.Result = TaskMethod("Background worker", 5);
};
worker.RunWorkerCompleted += (sender, eventArgs) =>
{
if (eventArgs.Error != null)
{
tcs.SetException(eventArgs.Error);
}
else if (eventArgs.Cancelled)
{
tcs.SetCanceled();
}
else
{
try
{
// 将 SetResult 方法封装在 try-catch 中,保证发生错误时仍然会设置给任务完成源对象
// 若发生异常导致没有执行 SetResult,则程序会一直阻塞在获取 Task 结果那里 (tcs.Task.Result)
tcs.SetResult((int)eventArgs.Result);
}
catch (Exception)
{
tcs.SetResult(0);
}
}
};
worker.RunWorkerAsync();
int result = tcs.Task.Result;
Console.WriteLine($"Result is: {result}");
Console.ReadLine();
}
static int TaskMethod(string name, int seconds)
{
Console.WriteLine($"Task {name} is running on a thread id {Thread.CurrentThread.ManagedThreadId}. " +
$"Is thread pool thread: {Thread.CurrentThread.IsThreadPoolThread}");
Thread.Sleep(TimeSpan.FromSeconds(seconds));
return 42 * seconds;
}
打印结果
txt
Task Background worker is running on a thread id 3. Is thread pool thread: True
Result is: 210