Xamarin应用程序在动态参数返回时崩溃

问题描述 投票:1回答:2

我正在尝试在我的Xamarin应用程序中创建异常拦截器。现在我正试图拦截服务的方法:从视图模型到商务逻辑的调用(所有在一个项目中,完整的.net标准2)。

我依靠this回答(使用autofac)并发现它简单而聪明。它工作正常,我添加一个try-catch来获取我的异常,到目前为止一切顺利。但后来我尝试在DTO对象类型中返回异常。我们所有的服务都返回一个源自DTOBase抽象类的DTO类的Task。这些类只包含对值的引用和名为IEnumerable的异常的Errors。所以基本上,我尝试捕获异常,将它放在错误列表中并返回我的对象​​。我完成了这段代码:

public class ExceptionInterceptorBehaviour : IInterceptor
    {
        public void Intercept(IInvocation invocation)
        {
            invocation.Proceed();
            var method = invocation.MethodInvocationTarget;
            var isAsync = method.GetCustomAttribute(typeof(AsyncStateMachineAttribute)) != null;
            if (isAsync && typeof(Task).IsAssignableFrom(method.ReturnType))
            {
                invocation.ReturnValue = InterceptAsync((dynamic)invocation.ReturnValue);
            }
        }

        private static async Task InterceptAsync(Task task)
        {
            await task.ConfigureAwait(false);
        }

        private static async Task<T> InterceptAsync<T>(Task<T> task)
        {
            try
            {
                T result = await task.ConfigureAwait(false);
                return result;
            }
            catch (Exception e)
            {
                if (typeof(DTOBase).IsAssignableFrom(typeof(T)))
                {
                    var ret = Activator.CreateInstance(typeof(T));
                    (ret as DTOBase).Errors.Add(e);
                    return (T)ret;
                }
                throw e;
            }
        }
    }

我的问题是应用程序在Task<T> InterceptAsync<T>(Task<T> task)返回时崩溃。没有异常,调试器中没有暂停模式只是一个简单的崩溃。我怀疑是分段错误,但是我的演员确实有效(我测试了它)并且我确实返回了Task<T>并将其分配给Task<T>对象。

我错过了什么吗?我不明白为什么它会像那样崩溃。

c# .net .net-standard
2个回答
0
投票

这是在iOS上发生的吗? Xamarin有一些由其底层平台定义的limitations。动态代码就是其中之一。避免使用dynamic


0
投票

所以,我考虑了rubo的答案并用dynamic变量重写我的代码并最终得到:

public class ExceptionInterceptorBehaviour : IInterceptor
    {
        public void Intercept(IInvocation invocation)
        {
            invocation.Proceed();
            var method = invocation.MethodInvocationTarget;
            var isAsync = method.GetCustomAttribute(typeof(AsyncStateMachineAttribute)) != null;
            if (isAsync && typeof(Task).IsAssignableFrom(method.ReturnType))
            {
                if (method.ReturnType.IsGenericType)
                {
                    invocation.ReturnValue = typeof(ExceptionInterceptorBehaviour)
                        .GetMethod("InterceptGenericAsync", BindingFlags.Instance | BindingFlags.NonPublic)
                        .MakeGenericMethod(method.ReturnType.GenericTypeArguments[0])
                        .Invoke(this, new object[] { invocation.ReturnValue });
                }
                else
                {
                    invocation.ReturnValue = InterceptAsync((Task)invocation.ReturnValue);
                }
            }
        }

        private async Task InterceptAsync(Task task)
        {
            await task.ConfigureAwait(false);
        }

        private async Task<T> InterceptGenericAsync<T>(Task<T> task)
        {
            try
            {
                object result = await task.ConfigureAwait(false);
                return (T)result;
            }
            catch (Exception e)
            {
                if (typeof(DTOBase).IsAssignableFrom(typeof(T)))
                {
                    var ret = Activator.CreateInstance(typeof(T));
                    (ret as DTOBase).Errors.Add(e);
                    return (T)ret;
                }
                throw e;
            }
        }
    }

有趣的事实是,当我试图在调试中退出InterceptGenericAsync时,代码仍然崩溃,但是如果我让它运行它可以正常工作,这很奇怪和可怕。我没有在iOS上测试这个解决方案,我不确定它是否正常工作。

© www.soinside.com 2019 - 2024. All rights reserved.