在IIS Express上使用SignalR和ASP.NET MVC 3启动时偶尔会出现异常

时间:2012-08-09 21:31:47

标签: asp.net asp.net-mvc-3 signalr signalr-hub

我正在为使用ASP.NET MVC 3和SignalR 0.5.2的服务器软件编写内部Web应用程序。我们偶尔会在启动时看到以下异常:

System.InvalidOperationException: This method cannot be called during the application's pre-start initialization stage.

Server stack trace: 
   at System.Web.Compilation.BuildManager.EnsureTopLevelFilesCompiled()
   at System.Web.Compilation.BuildManager.GetReferencedAssemblies()
   at SignalR.Hosting.AspNet.Infrastructure.AspNetAssemblyLocator.GetAssemblies()
   at SignalR.Hubs.ReflectedHubDescriptorProvider.BuildHubsCache()
   at System.Lazy`1.CreateValue()

Exception rethrown at [0]: 
   at System.Lazy`1.get_Value()
   at SignalR.Hubs.ReflectedHubDescriptorProvider.TryGetHub(String hubName, HubDescriptor& descriptor)
   at SignalR.Hubs.DefaultHubManager.<>c__DisplayClass1.<GetHub>b__0(IHubDescriptorProvider p)
   at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
   at SignalR.Hubs.DefaultHubManager.GetHub(String hubName)
   at SignalR.Hubs.HubManagerExtensions.EnsureHub(IHubManager hubManager, String hubName)
   at SignalR.Hubs.HubDispatcher.GetSignals(ClientHubInfo hubInfo, String connectionId)
   at SignalR.Hubs.HubDispatcher.<>c__DisplayClass23.<CreateConnection>b__22(ClientHubInfo info)
   at System.Linq.Enumerable.<SelectManyIterator>d__14`2.MoveNext()
   at System.Linq.Enumerable.<ConcatIterator>d__71`1.MoveNext()
   at System.Collections.Generic.HashSet`1.UnionWith(IEnumerable`1 other)
   at System.Collections.Generic.HashSet`1..ctor(IEnumerable`1 collection, IEqualityComparer`1 comparer)
   at SignalR.Connection..ctor(IMessageBus messageBus, IJsonSerializer jsonSerializer, String baseSignal, String connectionId, IEnumerable`1 signals, IEnumerable`1 groups, ITraceManager traceManager)
   at SignalR.Hubs.HubDispatcher.CreateConnection(String connectionId, IEnumerable`1 groups, IRequest request)
   at SignalR.PersistentConnection.ProcessRequestAsync(HostContext context)
   at SignalR.Hubs.HubDispatcher.ProcessRequestAsync(HostContext context)
   at SignalR.Hosting.AspNet.AspNetHandler.ProcessRequestAsync(HttpContextBase context)
   at SignalR.Hosting.AspNet.HttpTaskAsyncHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData)
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

我怀疑发生这种情况是因为我们正在重新启动IIS Express时打开一个浏览器,它正在向集线器路由映射和初始化完成之间的确切时刻发出请求(通过SignalR javascript)。我可能完全错误的原因,遗憾的是我们无法可靠地重现这一点,这是我的第一个ASP.NET项目,所以我很遗憾可能会发生什么。

这是我们在App_Start文件夹中的NinjectWebCommon.cs文件:

[assembly: WebActivator.PreApplicationStartMethod(typeof(WebStatusClient.App_Start.NinjectWebCommon), "Start")]
[assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(WebStatusClient.App_Start.NinjectWebCommon), "Stop")]

namespace WebStatusClient.App_Start
{
    using System;
    using System.Web;

    using Microsoft.Web.Infrastructure.DynamicModuleHelper;

    using Ninject;
    using Ninject.Web.Common;
    using SignalR.Infrastructure;
    using SignalR.Ninject;
    using SignalR;
    using System.Web.Routing;

    public static class NinjectWebCommon 
    {
        private static readonly Bootstrapper bootstrapper = new Bootstrapper();

        public static StandardKernel Kernel { get; private set; }

        /// <summary>
        /// Starts the application
        /// </summary>
        public static void Start() 
        {
            DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
            DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
            bootstrapper.Initialize(CreateKernel);

            RouteTable.Routes.MapHubs();
        }

        /// <summary>
        /// Stops the application.
        /// </summary>
        public static void Stop()
        {
            bootstrapper.ShutDown();
        }

        /// <summary>
        /// Creates the kernel that will manage your application.
        /// </summary>
        /// <returns>The created kernel.</returns>
        private static IKernel CreateKernel()
        {
            Kernel = new StandardKernel();
            Kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
            Kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();

            RegisterServices(Kernel);
            return Kernel;
        }

        /// <summary>
        /// Load your modules or register your services here!
        /// </summary>
        /// <param name="kernel">The kernel.</param>
        private static void RegisterServices(IKernel kernel)
        {
            kernel.Bind<Impl.StatusForwarder>()
                .To<Impl.StatusForwarder>()
                .InSingletonScope();

            kernel.Bind<StatusInterfaceClient.IStatusNotificationTarget>()
                .ToMethod(context => context.Kernel.Get<Impl.StatusForwarder>());

            // Set the SignalR dependency injector.
            SignalR.GlobalHost.DependencyResolver = new SignalR.Ninject.NinjectDependencyResolver(kernel);

            // Force the creation of the status manager.
            Impl.StatusInterfaceManager.Initialize();
        }
    }
}

有任何关于弄清楚可能出错的建议吗?我应该在初始化过程中稍后映射集线器吗?

0 个答案:

没有答案