C# Xamarin应用程序在具有动态参数返回的函数处崩溃

C# Xamarin应用程序在具有动态参数返回的函数处崩溃,c#,.net,.net-standard,C#,.net,.net Standard,我正在尝试在我的Xamarin应用程序中创建一个异常拦截器。现在,我正试图截取服务的方法:从视图模型到业务逻辑的调用(全部在一个项目中,完整的.net标准2) 我偶然发现了答案(使用autofac),发现它简单而聪明。它工作得很好,我添加了一个try-catch来获取我的异常,到目前为止还不错。 但后来我尝试以DTO对象类型返回我的异常。我们的所有服务都返回一个从DTOBase抽象类派生的DTO类的任务。这些类只包含对名为Errors的异常值和IEnumerable的引用。 因此,基本上,我尝试

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

我偶然发现了答案(使用autofac),发现它简单而聪明。它工作得很好,我添加了一个try-catch来获取我的异常,到目前为止还不错。 但后来我尝试以DTO对象类型返回我的异常。我们的所有服务都返回一个从
DTOBase
抽象类派生的DTO类的任务。这些类只包含对名为
Errors
的异常值和
IEnumerable
的引用。 因此,基本上,我尝试捕获异常,将其放入错误列表并返回我的对象。我完成了以下代码:

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;
            }
        }
    }
公共类例外Interceptor行为:IIInterceptor
{
公共无效拦截(IInvocation调用)
{
invocation.procedure();
var method=invocation.MethodInvocationTarget;
var isAsync=method.GetCustomAttribute(typeof(AsyncStateMachineAttribute))!=null;
if(isAsync&&typeof(Task).IsAssignableFrom(method.ReturnType))
{
invocation.ReturnValue=InterceptAsync((动态)invocation.ReturnValue);
}
}
专用静态异步任务侦听异步(任务任务)
{
等待任务。配置等待(false);
}
专用静态异步任务侦听异步(任务任务)
{
尝试
{
T结果=等待任务。配置等待(false);
返回结果;
}
捕获(例外e)
{
if(typeof(DTOBase).IsAssignableFrom(typeof(T)))
{
var ret=Activator.CreateInstance(typeof(T));
(以DTOBase形式返回)。错误。添加(e);
返回(T)ret;
}
投掷e;
}
}
}
我的问题是,应用程序在返回
Task InterceptAsync(Task Task)
时崩溃。没有引发异常,调试器中没有暂停模式,只是简单的崩溃。 我怀疑有分段错误,但我的cast确实有效(我测试了它),我确实返回了一个
任务
,并将其分配给
任务
对象


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

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

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

因此,我考虑了rubo的答案,并用no
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;
            }
        }
    }
公共类例外Interceptor行为:IIInterceptor
{
公共无效拦截(IInvocation调用)
{
invocation.procedure();
var method=invocation.MethodInvocationTarget;
var isAsync=method.GetCustomAttribute(typeof(AsyncStateMachineAttribute))!=null;
if(isAsync&&typeof(Task).IsAssignableFrom(method.ReturnType))
{
if(方法.ReturnType.IsGenericType)
{
invocation.ReturnValue=typeof(ExceptionInterceptorBehavior除外)
.GetMethod(“InterceptGenericAsync”,BindingFlags.Instance | BindingFlags.NonPublic)
.MakeGenericMethod(方法.ReturnType.GenericTypeArguments[0])
.Invoke(这是新对象[]{invocation.ReturnValue});
}
其他的
{
invocation.ReturnValue=InterceptAsync((任务)invocation.ReturnValue);
}
}
}
专用异步任务侦听异步(任务任务)
{
等待任务。配置等待(false);
}
专用异步任务InterceptGenericAsync(任务任务)
{
尝试
{
对象结果=等待任务。配置等待(false);
返回(T)结果;
}
捕获(例外e)
{
if(typeof(DTOBase).IsAssignableFrom(typeof(T)))
{
var ret=Activator.CreateInstance(typeof(T));
(以DTOBase形式返回)。错误。添加(e);
返回(T)ret;
}
投掷e;
}
}
}
有趣的事实是,当我试图在调试中退出
InterceptGenericAsync
时,代码仍在崩溃,但如果让它运行,它就可以正常工作,这既奇怪又可怕。
不过,我没有在iOS上测试这个解决方案,我不确定它是否工作。

因此,我考虑了rubo的答案,并用无
动态
变量重写了我的代码,结果是:

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;
            }
        }
    }
公共类例外Interceptor行为:IIInterceptor
{
公共无效拦截(IInvocation调用)
{
invocation.procedure();
var method=invocation.MethodInvocationTarget;
var isAsync=method.GetCustomAttribute(typeof(AsyncStateMachineAttribute))!=null;
if(isAsync&&typeof(Task).IsAssignableFrom(method.ReturnType))
{
if(方法.ReturnType.IsGenericType)
{
invocation.ReturnValue=typeof(ExceptionInterceptorBehavior除外)
.GetMethod(“InterceptGenericAsync”,BindingFlags.Instance | BindingFlags.NonPublic)
.MakeGenericMethod(方法.ReturnType.GenericTypeArguments[0])
.Invoke(这是新对象[]{invocation.ReturnValue});
}
其他的
{
invocation.ReturnValue=InterceptAsync((任务)invocation.ReturnValue);