我想使用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..Task.ContinueWith”周围使用一个try-catch块?
答案 0 :(得分:1)
使用Task.ContinueWith时在哪里捕获异常?
正确的答案是“不要使用ContinueWith
”。对于异步代码,可以使用await
来代替;对于这样的同步代码,您什么也不能使用:
public async TaskCreateAndUploadAsync()
{
await Task.Run(async () =>
{
try
{
var _writeFile = new WriteFile(...);
_writeFile.DoWork();
storage.UploadCreatedObject(...);
}
catch (Exception e)
{
//Log..
}
});
}
但是,wrapping a method body in Task.Run
like this is an antipattern;最好使该方法保持同步并让调用方使用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
。