c# - 正确使用 return Task.FromException
问题描述
我最近观察了两个开发人员之间的代码审查。
提交了以下代码:
public async Task<List<Thing>> GetThings()
{
try
{
var endpoint = $"{Settings.ThingEndpoint}/things";
var response = await HttpClient.GetAsync(endpoint);
return JsonConvert.DeserializeObject<List<Thing>>(await response.Content.ReadAsStringAsync());
}
catch (Exception e)
{
Log.Logger.Error(e.ToString());
return await Task.FromException<List<Thing>>(e);
}
}
其中收到以下审查意见:
绝对不需要返回 await Task.FromException>(e),这是你在处理非等待任务时要做的事情。在这种情况下,catch 将捕获任何异常 var response = await HttpClient.GetAsync(endpoint); 会扔。您应该删除它并按原样捕获异常
我不完全理解为什么不使用 Task.FromException 在这种情况下,所以我有以下问题:
- 审稿人在说什么?
- 审稿人正确吗?
- 为什么不返回 await Task.FromException?
- 返回 await Task.FromException 的正确方案是什么?
解决方案
审稿人完全正确。
您将使用的唯一情况Task.FromException
是当您处于无法或不会使用async
and实现的方法中await
,并且您希望任务的结果应该是异常时。
白痴的例子,但无论如何:
public Task<int> NotReallyAsync()
{
if (new Random().Next(2) == 0)
return Task.FromResult(42);
return Task.FromException<int>(new InvalidOperationException());
}
那么让我们一一处理您的问题:
审阅者说
Task.FromException
应该只在非async
/await
方法中使用,在async
/await
方法中,您应该只重新抛出异常:catch (Exception e) { Log.Logger.Error(e.ToString()); throw; }
或者如果您实施异常过滤器:
catch (Exception e) when (Log.Logger.ExceptionFilter(e)) { }
是的,审稿人是对的。
- 因为它是不必要的,所以只是重新抛出异常。如果你想抛出异常,只需抛出它。
async
/的目的await
是为了能够以正常的方式编写你的方法,所以编写一个正常的 throw 语句或一个正常的 catch-block。 - 非
async
/await
方法,仅此而已。
推荐阅读
- c# - 链接的键盘键与它们链接的表单按钮的行为不同
- bash - 读取:在 bash 中读取输入时不是有效的标识符
- java - FXML 文件中的加载异常错误阻止程序运行
- windows - imagemagick 批处理命令后的错误级别 0
- google-apps-script - 如何在 Google 表格中创建 Marimekko 图表?
- c - 为什么 C 输出中的自引用结构为空
- android - 使用 Android 8.0 的华为特有的 Android 原生崩溃 (tgKill)
- angular - Angular 根据当前模块改变页眉和页脚
- flutter - 使用 Android 警报管理器和隔离器 Flutter 后台进程
- python - 如何从调用 python 脚本的 bash 脚本转到调用 bash 脚本的 python 脚本?