exception - 使用 Task.ContinueWith 时在哪里捕获异常?
问题描述
我想用 Task 创建一个异步方法,它创建一个文件并立即继续执行下一个将创建的文件上传到云的任务。这是此方法的外观:
public async TaskCreateAndUploadAsync()
{
await Task.Run(() =>
{
try
{
var _writeFile = new WriteFile(...);
_writeFile.DoWork();
}
catch (Exception e)
{
//Log..
}
}).ContinueWith((result) =>
{
if (!result.IsFaulted)
{
try
{
storage.UploadCreatedObject(...);
}
catch (Exception e)
{
//Log..
}
}
});
}
我的问题是:我如何在每个任务中单独捕获异常的方式是否正确,或者我应该在整个“Task..Task.ContinueWith”周围使用一个 try-catch 块?
解决方案
使用 Task.ContinueWith 时在哪里捕获异常?
正确的答案是“不要使用ContinueWith
”。对于异步代码,可以await
改用;对于这样的同步代码,你可以什么都不用:
public async TaskCreateAndUploadAsync()
{
await Task.Run(async () =>
{
try
{
var _writeFile = new WriteFile(...);
_writeFile.DoWork();
storage.UploadCreatedObject(...);
}
catch (Exception e)
{
//Log..
}
});
}
但是,像这样包装方法体Task.Run
是一种反模式;最好保持方法同步并让调用者使用Task.Run
:
public void TaskCreateAndUpload()
{
try
{
var _writeFile = new WriteFile(...);
_writeFile.DoWork();
storage.UploadCreatedObject(...);
}
catch (Exception e)
{
//Log..
}
}
从您的方法名称来看,听起来其中一些应该是异步的。I/O 本质上是异步的。因此,如果您有真正的异步 I/O(即,不Task.Run
用于伪异步),那么您得到的方法可能如下所示:
public async Task TaskCreateAndUploadAsync()
{
try
{
var _writeFile = new WriteFile(...);
await _writeFile.DoWorkAsync();
await storage.UploadCreatedObjectAsync(...);
}
catch (Exception e)
{
//Log..
}
}
请注意在最后一个示例中使用了await
代替。ContiueWith
推荐阅读
- python - 将 2182869 等大数格式化为 2.1E8
- sql - 计划的作业没有执行我的 PLSQL 块
- c# - 如何在 Viewbag 中设置为字符串的 MVC 视图中显示/转换货币符号
- gmail - 电子邮件基础:Gmail 应用程序中的小视图端口
- ms-access - 在 Access VBA 中打开 RecordSet 时,如果类型为 dbOpenSnapshot,是否会使选项 dbReadOnly 变得多余?
- javascript - react/redux 正在注册 2 个对 reducer 的调用,即使该操作仅触发一次
- c# - How to get selected value of item from dropdownlist inside formview?
- parse-platform - Parse Server - 您在单页应用程序中将会话令牌存储在哪里?
- php - PHP json array manipulation
- sql-server - 运行缓慢的累积总 SQL Server 更新查询