所以我理解为什么从异步中返回void通常没有任何意义,但我遇到了一种我认为完全有效的情况.考虑以下人为的例子:
protected override void OnLoad(EventArgs e)
{
if (CustomTask == null)
// Do not await anything, let OnLoad return.
PrimeCustomTask();
}
private TaskCompletionSource<int> CustomTask;
// I DO NOT care about the return value from this. So why is void bad?
private async void PrimeCustomTask()
{
CustomTask = new TaskCompletionSource<int>();
int result = 0;
try
{
// Wait for button click to set the value, but do not block the UI.
result = await CustomTask.Task;
}
catch
{
// Handle exceptions
}
CustomTask = null;
// Show the value
MessageBox.Show(result.ToString());
}
private void button1_Click(object sender, EventArgs e)
{
if (CustomTask != null)
CustomTask.SetResult(500);
}
Run Code Online (Sandbox Code Playgroud)
我意识到这是一个不寻常的例子,但我试图让它更简单,更通用.有人可以向我解释为什么这是可怕的代码,以及我如何修改它以正确遵循约定?
谢谢你的帮助.
Ste*_*ary 20
好吧,通过"避免async void"文章中的原因:
PrimeCustomTask处理将非常尴尬.PrimeCustomTask那里,就是它 - 它不能被组成一个更高层次的async方法.PrimeCustomTask(或任何调用它的东西).同样重要的是要注意这async Task是自然的方法.在采用async/await的几种语言中,C#/ VB是唯一支持AFAIK的语言async void.F#没有,Python没有,JavaScript和TypeScript没有.async void从语言设计的角度看是不自然的.
async void添加到C#/ VB 的原因是为了启用异步事件处理程序.如果您更改代码以使用async void事件处理程序:
protected override async void OnLoad(EventArgs e)
{
if (CustomTask == null)
await PrimeCustomTask();
}
private async Task PrimeCustomTask()
Run Code Online (Sandbox Code Playgroud)
然后,async void缺点仅限于您的事件处理程序.特别是,异常PrimeCustomTask会自然地传播到它的(异步)调用者(OnLoad),PrimeCustomTask可以组合(从其他异步方法自然地调用),并且PrimeCustomTask更容易包含在单元测试中.
使用void async通常只被视为"坏",因为:
有很多案例(比如你的)使用它很好.使用它时要小心.
| 归档时间: |
|
| 查看次数: |
7660 次 |
| 最近记录: |