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

时间:2019-03-25 15:31:05

标签: c# .net .net-standard

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

我偶然发现了ExcelJet答案(使用autofac),并发现它简单而聪明。一切正常,到目前为止,我添加了一个try-catch来获取异常。 但是后来我尝试以DTO对象类型返回异常。我们所有的服务都返回从value抽象类派生的DTO类的Task。这些类仅包含对值的引用和名为DTOBase的异常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>对象。

我想念什么吗?我不明白为什么它会崩溃。

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分: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上测试此解决方案,但不确定它是否有效。