【发布时间】:2012-12-26 14:53:10
【问题描述】:
下面是实现Castle Dynamic Proxy 库的IInterceptor 的自定义类型上的Intercept 方法的代码。此 sn-p 来自基于 AOP 的日志记录概念验证控制台应用程序,该应用程序发布在 here。
public void Intercept(IInvocation invocation)
{
if (Log.IsDebugEnabled) Log.Debug(CreateInvocationLogString("Called", invocation));
try
{
invocation.Proceed();
if (Log.IsDebugEnabled)
if (invocation.Method.ReturnType != typeof(void))
Log.Debug("Returning with: " + invocation.ReturnValue);
}
catch (Exception ex)
{
if (Log.IsErrorEnabled) Log.Error(CreateInvocationLogString("ERROR", invocation), ex);
throw;
}
}
这在常规方法调用中按预期工作,但在使用 async 方法(使用 C# 5.0 中的 async/await 关键字)尝试时却不行。我相信,我也理解这背后的原因。
为了使async/await起作用,编译器将方法的功能体添加到幕后的状态机中,一旦出现第一个无法同步完成的awaitable表达式,控制权就会返回给调用者, 遇到了。
此外,我们可以询问返回类型并确定我们是否正在处理这样的async 方法:
if (invocation.Method.ReturnType == typeof(Task) ||
(invocation.Method.ReturnType.IsGenericType &&
invocation.Method.ReturnType.GetGenericTypeDefinition() == typeof(Task<>)))
Log.Info("Asynchronous method found...");
这仅适用于那些返回 Task 或 Task<> 而不是 void 的 async 方法,但我可以接受。
必须在Intercept 方法中进行哪些更改才能使awaiter 返回到那里而不是原来的调用者?
【问题讨论】:
标签: c# reflection aop async-await castle-dynamicproxy