c# - 在 Azure 函数中捕获异步方法异常
问题描述
我已经使用 C#(库项目)和 Aspect (AOP) 编写了 Azure 函数 v1 以进行日志记录。我没有在 catch 块中遇到异常。
我有上面讨论过的相同问题,但是,Azure Function Run 方法是 Async Task,其异常处理与 async void 相同。不知道哪里出了问题?假设这是功能 SDK 问题。
天蓝色函数
public static class PingFunction
{
[LoggerAspect]
[FunctionName("PingFunction")]
public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)]HttpRequestMessage req, TraceWriter log)
{
string name = string.Empty;
log.Info("C# HTTP trigger function processed a request.");
SomeService someService = new SomeService();
await someService.DoSomething();
return req.CreateResponse(HttpStatusCode.OK, "Hello " + name);
}
}
public class SomeService
{
public async Task DoSomething()
{
await Task.Delay(1000);
throw new Exception("Exception from Service");
}
}
记录器方面(MrAdvise)
public class LoggerAspectAttribute : Attribute, IMethodAdvice
{
public void Advise(MethodAdviceContext context)
{
//Logger initilizer here
Console.WriteLine($"{context.TargetType.Name} started...");
try
{
context.Proceed(); // this calls the original method
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
Console.WriteLine($"{context.TargetType.Name} completed...");
}
}
}
解决方法 当我从 Azure 函数中删除 Async-await 并通过“ GetAwaiter().GetResult() ”调用异步方法时,它就可以工作了。
public static HttpResponseMessage Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)]HttpRequestMessage req, TraceWriter log)
{
string name = string.Empty;
log.Info("C# HTTP trigger function processed a request.");
SomeService someService = new SomeService();
someService.DoSomething().GetAwaiter().GetResult();
return req.CreateResponse(HttpStatusCode.OK, "Hello " + name);
}
Task.GetAwaiter().GetResult() 方法可能会导致死锁问题,应避免使用 async/await。
我的函数每天处理数百万个事件。如果这是 FunctionSDK 问题或其他问题,这是正确的解决方案吗?
解决方案
您需要编写异步建议,例如:
public class LoggerAspectAttribute : Attribute, IMethodAsyncAdvice
{
public async Task Advise(MethodAsyncAdviceContext context)
{
//Logger initilizer here
Console.WriteLine($"{context.TargetType.Name} started...");
try
{
await context.ProceedAsync(); // this calls the original method
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
Console.WriteLine($"{context.TargetType.Name} completed...");
}
}
}
编辑:是的,它适用于 Mr Advice :)
推荐阅读
- macos - 将数百万张图像从 Macos 移动/复制到外部驱动器到 ubuntu 服务器
- javascript - 我们如何在 Vue-cli 中导入外部脚本
- google-bigquery - 是否可以在 BigQuery 中取消嵌套数组,以便将嵌套数据按键值拆分为列?
- php - 如果数组中出现空值,则向数组添加零
- java - 使用 JSch 将文件内容下载到字符串
- android - Camera 2 API 会降低拍摄后的质量
- java - 是否可以为 API 范围定义特定尺寸?
- java - 使用 Spring JPA 如何从 DB 视图中读取多个参考数据
- linux - 如何将静态库嵌入到共享库中?
- reactjs - 将参数传递给 react-apollo-hooks useQuery