截取呼叫使用DynamicProxy异步方法 [英] Intercept the call to an async method using DynamicProxy

查看:144
本文介绍了截取呼叫使用DynamicProxy异步方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是从拦截方法code上的自定义类型实现 IInterceptor 的< A HREF =htt​​p://www.castleproject.org/projects/dynamicproxy/>城堡动态代理库。这片段是从证明AOP的概念基于日志的控制台应用程序,发布的此处

Below is the code from the Intercept method on a custom type that implements IInterceptor of the Castle Dynamic Proxy library. This snippet is from an AOP based logging proof-of-concept console app that is posted 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;
        }
    }

这是按预期工作在普通的方法调用,但与异步方法试图不(使用异步/的await 从C#5.0关键字)。而且我相信,我明白这背后的原因也是如此。

This is working as expected on regular method calls, but not when tried with async methods (using the async/await keywords from C# 5.0). And I believe, I understand the reasons behind this as well.

对于异步/的await 来上班时,编译器会将方法的职能机构到幕后状态机和控制将返回给调用者,如只要第一个 awaitable 前pression无法同步完成,遇到。

For the async/await to work, the compiler adds the functional body of the method into a state machine behind the scenes and the control will return to the caller, as soon as the first awaitable expression that cannot be completed synchronously, is encountered.

此外,我们还可以查询的返回类型,弄清我们是否正在处理一个异步的方法是这样的:

Also, we can interrogate the return type and figure out whether we are dealing with an async method like this:

            if (invocation.Method.ReturnType == typeof(Task) || 
                (invocation.Method.ReturnType.IsGenericType && 
                 invocation.Method.ReturnType.GetGenericTypeDefinition() == typeof(Task<>)))
                Log.Info("Asynchronous method found...");

这适用于仅返回要么工作任务&LT那些异步方法;&GT ; ,而不是无效,但我很好与

This works for only those async methods that returns either Task or Task<> and not void but I am fine with that.

有什么变化的拦截方法内进行,使 awaiter 将回到那里,而不是原来的呼叫者?

What changes have to made within the Intercept method so that the awaiter would return to there rather than the original caller?

推荐答案

presumably问题在于,它只是记录,它的返回一个任务 - 你想要的的内任务是什么?

Presumably the "problem" is that it's just logging that it's returning a task - and you want the value within that task?

假设是这样的话,你还是要任务返回给调用者,立即 - 无需等待它完成。如果你打破了,你是从根本上搞乱的东西了。

Assuming that's the case, you still have to return the task to the caller, immediately - without waiting for it to complete. If you break that, you're fundamentally messing things up.

不过,您返回任务调用者之前,你应该添加一个延续(通过<一个href=\"http://msdn.microsoft.com/en-us/library/system.threading.tasks.task.continuewith.aspx\"><$c$c>Task.ContinueWith)这将记录结果(或失败)的当任务完成的。这仍然会给结果信息,当然你会被其他的一些登录后可能记录它,你可能的的要返回前立即登录,导致日志是这样的:

However, before you return the task to the caller, you should add a continuation (via Task.ContinueWith) which will log the result (or failure) when the task completes. That will still give the result information, but of course you'll be logging it potentially after some other logging. You may also want to log immediately before returning, leading to a log something like this:

Called FooAsync
Returned from FooAsync with a task
Task from FooAsync completed, with return value 5

得到的结果淘汰任务(如果它成功完成)的业务将不得不与反思完成,这是一个痛苦位 - 或者你可以使用动态类型。 (无论哪种方式,这将是一个有点性能损失。)

The business of getting the result out of the task (if it completed successfully) would have to be done with reflection, which is a bit of a pain - or you could use dynamic typing. (Either way it will be a bit of a performance hit.)

这篇关于截取呼叫使用DynamicProxy异步方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆