相关疑难解决方法(0)

使用DynamicProxy拦截对异步方法的调用

下面是从代码Intercept上实现自定义类型的方法IInterceptor的的城堡动态代理库.此片段来自此处发布的基于AOP的日志记录概念验证控制台应用程序.

    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;
        }
    }
Run Code Online (Sandbox Code Playgroud)

这在常规方法调用中按预期工作,但在尝试使用async方法时(使用async/awaitC#5.0中的关键字)则不行.我相信,我也理解这背后的原因.

为了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...");
Run Code Online (Sandbox Code Playgroud)

这适用于那些async返回TaskTask<>不返回的方法, …

c# reflection aop castle-dynamicproxy async-await

27
推荐指数
3
解决办法
8226
查看次数

是否可以使用Castle.DynamicProxy创建异步交互?

我们基本上有一个如下所示的类,它使用Castle.DynamicProxy进行拦截.

using System;
using System.Collections.Concurrent;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Castle.DynamicProxy;

namespace SaaS.Core.IoC
{
    public abstract class AsyncInterceptor : IInterceptor
    {
        private readonly ILog _logger;

        private readonly ConcurrentDictionary<Type, Func<Task, IInvocation, Task>> wrapperCreators =
            new ConcurrentDictionary<Type, Func<Task, IInvocation, Task>>();

        protected AsyncInterceptor(ILog logger)
        {
            _logger = logger;
        }

        void IInterceptor.Intercept(IInvocation invocation)
        {
            if (!typeof(Task).IsAssignableFrom(invocation.Method.ReturnType))
            {
                InterceptSync(invocation);
                return;
            }

            try
            {
                CheckCurrentSyncronizationContext();
                var method = invocation.Method;

                if ((method != null) && typeof(Task).IsAssignableFrom(method.ReturnType))
                {
                    var taskWrapper = GetWrapperCreator(method.ReturnType);
                    Task.Factory.StartNew(
                        async () => …
Run Code Online (Sandbox Code Playgroud)

asynchronous castle-dynamicproxy

5
推荐指数
1
解决办法
1349
查看次数

Autofac拦截异步执行顺序

所以我有这门课:

public class MappingBootstrap : IMappingBootstrap
{
    public virtual async Task Map()
    {
        // Order is very important

        await this.mapper1.Map();

        await this.mapper2.Map();

        await this.mapper3.Map();

        await this.mapper4.Map();
    }
}
Run Code Online (Sandbox Code Playgroud)

我有Autofac拦截器:

public class LoggingInterceptor : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        var methodReference = Guid.NewGuid();
        Console.WriteLine($"Calling {invocation?.Method?.DeclaringType?.Name}.{invocation?.Method?.Name} : {methodReference}");

        var startNew = Stopwatch.StartNew();

        invocation?.Proceed();

        startNew.Stop();

        Console.WriteLine($"{methodReference} : Done, time taken: {startNew.ElapsedMilliseconds}ms");
    }
}
Run Code Online (Sandbox Code Playgroud)

这会产生输出:

调用IMapperBootstrap.Map:54425559-71fe-4f23-ab47-d0f3371ec819
调用IMapper1.Map:51babb34-fa83-42ed-84e7-a1e979528116
51babb34-fa83-42ed-84e7-a1e979528116:完成,所用时间:219ms
54425559-71fe-4f23- ab47-d0f3371ec819:完成,所用时间:221ms
呼叫IMapper2.Map:41c812a2-d82d-48f6-9b8d-139b52eb28e3
41c812a2-d82d-48f6-9b8d-139b52eb28e3:完成,所用时间:9ms
呼叫IMapper3.Map:c91bed04-8f86-47d3 -a35a-417e354c2c5f
c91bed04-8f86-47d3-a35a-417e354c2c5f:完成,所需时间:994ms
调用IMapper4.Map:035cad27-1ba8-4bd1-b85f-396f64998d97
035cad27-1ba8-4bd1-b85f-396f64998d97:完成,所用时间:18ms

正如您所看到的,MappingBoostrap.Map完成后的第一个Mapper1.Map而不是我期望的所有功能完成后的结束. …

c# autofac interception async-await

1
推荐指数
1
解决办法
1578
查看次数