运行 SignalR 自托管示例在最新的单声道开发分支中抛出异常

Running SignalR self-host samples throws exception with latest mono dev branch

在 Linux 上使用 Mono,在 https://github.com/SignalR/SignalR 中找到的示例 Microsoft.AspNet.SignalR.Mono 似乎可以使用稳定版本的 mono,但不适用于最新的开发分支 (3.99)。有人遇到过这个吗?我收到以下异常:

Unhandled Exception:
System.Reflection.TargetInvocationException: Exception has been thrown by the
target of an invocation. ---> System.InvalidProgramException: Invalid IL code
in (wrapper delegate-invoke)
<Module>:invoke_callvirt_CancellationTokenRegistration_CancellationToken&_Action`1<object>_object
(System.Threading.CancellationToken&,System.Action`1<object>,object): IL_004f:
castclass 0x00000007


  at
Microsoft.AspNet.SignalR.Infrastructure.CancellationTokenExtensions.SafeRegister
(CancellationToken cancellationToken, System.Action`1 callback, System.Object
state) [0x00000] in <filename unknown>:0 
  at
Microsoft.AspNet.SignalR.Hosting.HostDependencyResolverExtensions.InitializeResolverDispose
(IDependencyResolver resolver, CancellationToken hostShutdownToken) [0x00000]
in <filename unknown>:0 
  at
Microsoft.AspNet.SignalR.Hosting.HostDependencyResolverExtensions.InitializeHost
(IDependencyResolver resolver, System.String instanceName, CancellationToken
hostShutdownToken) [0x00000] in <filename unknown>:0 
  at Owin.OwinExtensions.UseSignalRMiddleware[PersistentConnectionMiddleware]
(IAppBuilder builder, System.Object[] args) [0x00000] in <filename unknown>:0 
  at Owin.OwinExtensions.RunSignalR (IAppBuilder builder, System.Type
connectionType, Microsoft.AspNet.SignalR.ConnectionConfiguration configuration)
[0x00000] in <filename unknown>:0 
  at Owin.OwinExtensions.RunSignalR[RawConnection] (IAppBuilder builder,
Microsoft.AspNet.SignalR.ConnectionConfiguration configuration) [0x00000] in
<filename unknown>:0 
  at Owin.OwinExtensions.RunSignalR[RawConnection] (IAppBuilder builder)
[0x00000] in <filename unknown>:0 
  at Microsoft.AspNet.SelfHost.Samples.Startup.<Configuration>b__0 (IAppBuilder
map) [0x00000] in <filename unknown>:0 
  at Owin.MapExtensions.Map (IAppBuilder app, PathString pathMatch,
System.Action`1 configuration) [0x00000] in <filename unknown>:0 
  at Owin.MapExtensions.Map (IAppBuilder app, System.String pathMatch,
System.Action`1 configuration) [0x00000] in <filename unknown>:0 
  at Microsoft.AspNet.SelfHost.Samples.Startup.Configuration (IAppBuilder app)
[0x00000] in <filename unknown>:0 
  at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke
(System.Reflection.MonoMethod,object,object[],System.Exception&)
  at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags
invokeAttr, System.Reflection.Binder binder, System.Object[] parameters,
System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0 
  --- End of inner exception stack trace ---
  at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags
invokeAttr, System.Reflection.Binder binder, System.Object[] parameters,
System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0 
  at System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[]
parameters) [0x00000] in <filename unknown>:0 
  at Owin.Loader.DefaultLoader+<>c__DisplayClass12.<MakeDelegate>b__b
(IAppBuilder builder) [0x00000] in <filename unknown>:0 
  at Owin.Loader.DefaultLoader+<>c__DisplayClass1.<LoadImplementation>b__0
(IAppBuilder builder) [0x00000] in <filename unknown>:0 
  at Microsoft.Owin.Hosting.Engine.HostingEngine.ResolveApp
(Microsoft.Owin.Hosting.Engine.StartContext context) [0x00000] in <filename
unknown>:0 
  at Microsoft.Owin.Hosting.Engine.HostingEngine.Start
(Microsoft.Owin.Hosting.Engine.StartContext context) [0x00000] in <filename
unknown>:0 
  at Microsoft.Owin.Hosting.Starter.DirectHostingStarter.Start
(Microsoft.Owin.Hosting.StartOptions options) [0x00000] in <filename unknown>:0 
  at Microsoft.Owin.Hosting.Starter.HostingStarter.Start
(Microsoft.Owin.Hosting.StartOptions options) [0x00000] in <filename unknown>:0 
  at Microsoft.Owin.Hosting.WebApp.StartImplementation (IServiceProvider
services, Microsoft.Owin.Hosting.StartOptions options) [0x00000] in <filename
unknown>:0 
  at Microsoft.Owin.Hosting.WebApp.Start (Microsoft.Owin.Hosting.StartOptions
options) [0x00000] in <filename unknown>:0 
  at Microsoft.Owin.Hosting.WebApp.Start[Startup]
(Microsoft.Owin.Hosting.StartOptions options) [0x00000] in <filename unknown>:0 
  at Microsoft.Owin.Hosting.WebApp.Start[Startup] (System.String url) [0x00000]
in <filename unknown>:0 
  at Microsoft.AspNet.SelfHost.Samples.Program.Main (System.String[] args)
[0x00000] in <filename unknown>:0 
[ERROR] FATAL UNHANDLED EXCEPTION: System.Reflection.TargetInvocationException:
Exception has been thrown by the target of an invocation. --->
System.InvalidProgramException: Invalid IL code in (wrapper delegate-invoke)
<Module>:invoke_callvirt_CancellationTokenRegistration_CancellationToken&_Action`1<object>_object
(System.Threading.CancellationToken&,System.Action`1<object>,object): IL_004f:
castclass 0x00000007

SignalIR repo 上已经报告了该问题。尝试拉取最新版本的 dev 分支,ASP.NET 团队已经注释掉抛出该异常的代码作为目前的解决方法。

如果 IsRunningMono 为真,我最终选择 return ResolveRegisterDelegate() 中的回退寄存器:

if (MonoUtility.IsRunningMono)
    return fallback;

try
{
    methodInfo = typeof(CancellationToken).GetMethod("InternalRegisterWithoutEC",
                                                             BindingFlags.NonPublic | BindingFlags.Instance,
                                                             binder: null,
                                                             types: new[] { typeof(Action<object>), typeof(object) },
                                                             modifiers: null);

}
catch
{
    // Swallow this exception. Being extra paranoid, we don't want anything to break in case this dirty
    // reflection hack fails for any reason
}

我注意到这发生在较早的 mono 稳定版本中,因为 GetMethod("InternalRegisterWithoutEC") 是 returning null 并且在最新的开发分支中没有 return null单声道。

这看起来像是 Mono 更高版本中的错误。我在星期五报告了这个:http://bugzilla.xamarin.com/show_bug.cgi?id=29665