方式1:async/await模式
cs
private async void button1_Click(object sender, EventArgs e)
{
try
{
var result = await Task.Run(() => CalculateResult());
label1.Text = result.ToString();
}
catch (Exception ex)
{
label1.Text = $"Error: {ex.Message}";
}
}
private int CalculateResult()
{
System.Threading.Thread.Sleep(3000); // 模拟耗时计算
Random r = new Random();
int a = r.Next(1, 100);
int b = r.Next(1, 100);
return a + b;
}
方式2:回调注册模式
cs
private void button1_Click(object sender, EventArgs e)
{
var ts = RunAsyncTask();
RegisterCallback(ts, label1);
}
private Task<int> RunAsyncTask()
{
return Task.Run(() =>
{
System.Threading.Thread.Sleep(3000); // 模拟耗时计算
Random r = new Random();
int a = r.Next(1, 100);
int b = r.Next(1, 100);
return a + b;
});
}
private void RegisterCallback(Task<int> task,Label label)
{
task.GetAwaiter().OnCompleted(() =>
{
label.Invoke((MethodInvoker)delegate
{
label.Text = $"result: {task.Result}";
});
});
}
简化写法(方式2):
cs
private void button1_Click(object sender, EventArgs e)
{
RunAsyncTask()
.ContinueWith(t =>
{
label1.Invoke(new Action(() =>
{
label1.Text = t.IsFaulted ?
$"Error: {t.Exception?.InnerException?.Message}" :
$"Result: {t.Result}";
}));
}, TaskScheduler.Default);
}
private Task<int> RunAsyncTask()
{
return Task.Run(() =>
{
System.Threading.Thread.Sleep(3000); // 模拟耗时计算
Random r = new Random();
int a = r.Next(1, 100);
int b = r.Next(1, 100);
return a + b;
});
}
二、核心机制分析
1. 共同点
-
都使用
Task.Run
将耗时操作放到线程池执行 -
都能保持UI线程的响应性
-
最终都能正确更新UI控件
2. 关键差异
特性 | async/await模式 | 回调注册模式 |
---|---|---|
代码结构 | 线性流程,更易读 | 分散式,逻辑分离 |
线程上下文恢复 | 自动恢复UI上下文 | 需手动Invoke回UI线程 |
异常处理 | 可直接用try-catch | 需在回调中处理异常 |
可扩展性 | 相对固定 | 更灵活,可自定义回调逻辑 |
适用场景 | 简单异步操作 | 需要自定义完成逻辑的复杂场景 |
代码维护性 | 高,逻辑集中 | 较低,逻辑分散 |
调试难度 | 较低,有完整的调用栈 | 较高,调试异步回调较复杂 |
三、性能与资源比较
-
内存分配:
-
async/await会生成状态机,有额外分配
-
回调模式更直接,分配更少
-
-
执行效率:
-
实际计算性能几乎无差别
-
回调模式在极高并发下可能略有优势
-
-
线程使用:
-
两种方式都正确使用线程池
-
无实质性差异
-
四、最佳实践建议
优先使用async/await模式的情况:
-
简单的异步操作
-
需要清晰的代码流程
-
需要直接处理异常
-
团队对async/await更熟悉时
考虑使用回调模式的情况:
-
需要自定义任务完成后的处理逻辑
-
需要更精细控制任务生命周期
-
在性能敏感的极高并发场景
-
需要复用相同的回调逻辑时