深入研究CosmosDB和asybc调用后,我发现自己遇到了一些问题。我正在创建一个Web服务调用以删除CosmosDB文档,但是异常处理有点起作用,我认为这是因为异步调用的性质。基本上,异常不会在控制器上冒泡,执行正在跳开,导致调用在失败时看起来成功。
如何捕获DeleteDocumentAsync方法引发的异常,以便将相应的错误返回给调用客户端?
谢谢大家!
控制器代码:
[HttpDelete]
public ActionResult Delete(Guid key)
{
ActionResult result;
try
{
result = StatusCode(StatusCodes.Status200OK);
_repository.Delete<CodeKeyPairModel>(codeKeyPair);
return result;
}
catch (Exception ex)
{
_logger.LogError(ex, "Fatal error deleting record key", ex);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
</code>
存储库代码
public async void Delete<T>(T codeKeyPairModel) where T : CodeKeyPairModel
{
var documentLink = UriFactory.CreateDocumentUri(cosmosDBId, collectionId, codeKeyPairModel.Id.ToString());
var result = await cosmosDBClient.DeleteDocumentAsync(documentLink,
new RequestOptions() { PartitionKey = new PartitionKey(Undefined.Value) });
}
答案 0 :(得分:2)
存储库需要使用async Task
而不是async void
。 async void
是无法捕获异常的原因。
public async Task Delete<T>(T codeKeyPairModel) where T : CodeKeyPairModel {
var documentLink = UriFactory.CreateDocumentUri(cosmosDBId, collectionId, codeKeyPairModel.Id.ToString());
var result = await cosmosDBClient.DeleteDocumentAsync(documentLink,
new RequestOptions() { PartitionKey = new PartitionKey(Undefined.Value) });
}
引用Async/Await - Best Practices in Asynchronous Programming
异步void方法具有不同的错误处理语义。当从
async Task
或async Task<T>
方法抛出异常时,将捕获该异常并将其放置在Task对象上。使用async void
方法时,没有Task
对象,因此从async void
方法抛出的任何异常都将直接在{{1 }}方法开始。
第二,您的API代码通过不等待SynchronizationContext
中的任务来执行即发即弃模式。您需要async void
。
Delete