本文介绍了程序池循环后重新连接时MapSignalR MVC5挂起的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下的code在我Startup.SignalR.cs:

 使用Microsoft.AspNet.SignalR;
使用Owin;
使用系统;
使用System.Collections.Generic;
使用System.Linq的;
使用System.Text;
使用System.Threading.Tasks;命名空间管理
{
    公共部分类启动
    {
        公共无效ConfigureSignalR(IAppBuilder应用程序)
        {
            无功配置=新HubConfiguration()
            {
                EnableDetailedErrors =假,
                解析器=新DefaultDependencyResolver()
            };#如果DEBUG
            Config.EnableDetailedErrors = TRUE;
#万一
            //任何连接或集线器线和配置应该在这里
            app.MapSignalR();            GlobalHost.Configuration.ConnectionTimeout = TimeSpan.FromSeconds(600);
        }
    }
}

在应用程序的初始加载,一切都正常,但是当线程被允许睡觉(左为〜10分钟)的程序池被回收,线程卡住在这条线:

  app.MapSignalR();

IDE将被套牢绿色箭头和这是为了执行下一条语句时,从当前函数这个线程返回。。但是我不知道是什么当前函数在这种情况下是。

试图视察任何局部变量的结果不能评估前pression因为本地帧是在调用堆栈的顶部但是调用堆栈显示: ADMIN.DLL!Admin.Startup.ConfigureSignalR(Owin.IAppBuilder APP)第25行作为顶部框架...

在code从来没有从这种状态中恢复和程序池必须通过重新启动调试会话被完全重新启动。

任何人都有这种情况下任何交代?

更多信息:
启用后调试=> WINDOWS =>具有平行堆栈我看到更详细的堆栈跟踪:

  [托管到本机转换]
MSCORLIB.DLL!Microsoft.Win32.RegistryKey.OpenSubKey(字符串名称,布尔可写)
mscorlib.dll中!Microsoft.Win32.RegistryKey.OpenSubKey(字符串名称)
System.dll中!System.Diagnostics.PerformanceCounterLib.FindCustomCategory(串类,淘汰System.Diagnostics.PerformanceCounterCategoryType categoryType)
System.dll中!System.Diagnostics.PerformanceCounterLib.IsCustomCategory(弦机,串类)
System.dll中!System.Diagnostics.PerformanceCounter.InitializeImpl()
System.dll中!System.Diagnostics.PerformanceCounter.PerformanceCounter(字符串categoryName,字符串counterName,串实例名,布尔只读)
Microsoft.AspNet.SignalR.Core.dll!Microsoft.AspNet.SignalR.Infrastructure.PerformanceCounterManager.LoadCounter(string类别名称,字符串counterName,串实例名,布尔isReadOnly)
Microsoft.AspNet.SignalR.Core.dll!Microsoft.AspNet.SignalR.Infrastructure.PerformanceCounterManager.LoadCounter(string类别名称,字符串counterName,布尔isReadOnly)
Microsoft.AspNet.SignalR.Core.dll!Microsoft.AspNet.SignalR.Infrastructure.PerformanceCounterManager.SetCounterProperties()
Microsoft.AspNet.SignalR.Core.dll!Microsoft.AspNet.SignalR.Infrastructure.PerformanceCounterManager.Initialize(string实例名,System.Threading.CancellationToken hostShutdownToken)
Microsoft.AspNet.SignalR.Core.dll!Microsoft.AspNet.SignalR.Hosting.HostDependencyResolverExtensions.InitializePerformanceCounters(Microsoft.AspNet.SignalR.IDependencyResolver解析器,串实例名,System.Threading.CancellationToken hostShutdownToken)
Microsoft.AspNet.SignalR.Core.dll!Microsoft.AspNet.SignalR.Hosting.HostDependencyResolverExtensions.InitializeHost(Microsoft.AspNet.SignalR.IDependencyResolver解析器,串实例名,System.Threading.CancellationToken hostShutdownToken)
Microsoft.AspNet.SignalR.Core.dll!Owin.OwinExtensions.UseSignalRMiddleware<Microsoft.AspNet.SignalR.Owin.Middleware.HubDispatcherMiddleware>(Owin.IAppBuilder建设者,对象[]参数)
Microsoft.AspNet.SignalR.Core.dll!Owin.OwinExtensions.RunSignalR(Owin.IAppBuilder建设者,Microsoft.AspNet.SignalR.HubConfiguration配置)
Microsoft.AspNet.SignalR.Core.dll!Owin.OwinExtensions.MapSignalR.AnonymousMethod__0(Owin.IAppBuilder subApp)
!Microsoft.Owin.dll Owin.MapExtensions.Map(Owin.IAppBuilder应用程序,Microsoft.Owin.PathString pathMatch,System.Action&LT; Owin.IAppBuilder&GT;配置)
!Microsoft.Owin.dll Owin.MapExtensions.Map(Owin.IAppBuilder应用,串pathMatch,System.Action&LT; Owin.IAppBuilder&GT;配置)
Microsoft.AspNet.SignalR.Core.dll!Owin.OwinExtensions.MapSignalR(Owin.IAppBuilder建设者,路径字符串,Microsoft.AspNet.SignalR.HubConfiguration配置)
Microsoft.AspNet.SignalR.Core.dll!Owin.OwinExtensions.MapSignalR(Owin.IAppBuilder建设者,Microsoft.AspNet.SignalR.HubConfiguration配置)
Microsoft.AspNet.SignalR.Core.dll!Owin.OwinExtensions.MapSignalR(Owin.IAppBuilder建设者)
ADMIN.DLL!Admin.Startup.ConfigureSignalR(Owin.IAppBuilder APP)25号线


解决方案

正如帕维尔提到的,我是能够解决我的问题与使用虚拟性能计数器如下记载:的

  // Global.asmx
VAR tempCounterManager =新TempPerformanceCounterManager();
GlobalHost.DependencyResolver.Register(typeof运算(IPerformanceCounterManager),()=&GT; tempCounterManager);[...]//辅助类
公共类TempPerformanceCounterManager:IPerformanceCounterManager
{
    私人只读静态的PropertyInfo [] = _counterProperties GetCounterPropertyInfo();
    私人只读静态IPerformanceCounter _noOpCounter =新NoOpPerformanceCounter();    公共TempPerformanceCounterManager()
    {
        的foreach(在_counterProperties VAR属性)
        {
            property.SetValue(这一点,新NoOpPerformanceCounter(),NULL);
        }
    }    公共无效初始化(字符串实例名,的CancellationToken hostShutdownToken)
    {
    }    公共IPerformanceCounter LoadCounter(字符串categoryName,字符串counterName,串实例名,布尔isReadOnly)
    {
        返回_noOpCounter;
    }    内部静态的PropertyInfo [] GetCounterPropertyInfo()
    {
        返回的typeof(TempPerformanceCounterManager)
            .GetProperties()
            。凡(P =&GT; p.PropertyType == typeof运算(IPerformanceCounter))
            .ToArray();
    }
    公共IPerformanceCounter ConnectionsConnected {搞定;组; }
    公共IPerformanceCounter ConnectionsReconnected {搞定;组; }
    公共IPerformanceCounter ConnectionsDisconnected {搞定;组; }
    公共IPerformanceCounter ConnectionsCurrentForeverFrame {搞定;私人集; }
    公共IPerformanceCounter ConnectionsCurrentLongPolling {搞定;私人集; }
    公共IPerformanceCounter ConnectionsCurrentServerSentEvents {搞定;私人集; }
    公共IPerformanceCounter ConnectionsCurrentWebSockets {搞定;私人集; }
    公共IPerformanceCounter ConnectionsCurrent {搞定;私人集; }
    公共IPerformanceCounter ConnectionMessagesReceivedTotal {搞定;私人集; }
    公共IPerformanceCounter ConnectionMessagesSentTotal {搞定;私人集; }
    公共IPerformanceCounter ConnectionMessagesReceivedPerSec {搞定;私人集; }
    公共IPerformanceCounter ConnectionMessagesSentPerSec {搞定;私人集; }
    公共IPerformanceCounter MessageBusMessagesReceivedTotal {搞定;私人集; }
    公共IPerformanceCounter MessageBusMessagesReceivedPerSec {搞定;私人集; }
    公共IPerformanceCounter ScaleoutMessageBusMessagesReceivedPerSec {搞定;私人集; }
    公共IPerformanceCounter MessageBusMessagesPublishedTotal {搞定;私人集; }
    公共IPerformanceCounter MessageBusMessagesPublishedPerSec {搞定;私人集; }
    公共IPerformanceCounter MessageBusSubscribersCurrent {搞定;私人集; }
    公共IPerformanceCounter MessageBusSubscribersTotal {搞定;私人集; }
    公共IPerformanceCounter MessageBusSubscribersPerSec {搞定;私人集; }
    公共IPerformanceCounter MessageBusAllocatedWorkers {搞定;私人集; }
    公共IPerformanceCounter MessageBusBusyWorkers {搞定;私人集; }
    公共IPerformanceCounter MessageBusTopicsCurrent {搞定;私人集; }
    公共IPerformanceCounter ErrorsAllTotal {搞定;私人集; }
    公共IPerformanceCounter ErrorsAllPerSec {搞定;私人集; }
    公共IPerformanceCounter ErrorsHubResolutionTotal {搞定;私人集; }
    公共IPerformanceCounter ErrorsHubResolutionPerSec {搞定;私人集; }
    公共IPerformanceCounter ErrorsHubInvocationTotal {搞定;私人集; }
    公共IPerformanceCounter ErrorsHubInvocationPerSec {搞定;私人集; }
    公共IPerformanceCounter ErrorsTransportTotal {搞定;私人集; }
    公共IPerformanceCounter ErrorsTransportPerSec {搞定;私人集; }
    公共IPerformanceCounter ScaleoutStreamCountTotal {搞定;私人集; }
    公共IPerformanceCounter ScaleoutStreamCountOpen {搞定;私人集; }
    公共IPerformanceCounter ScaleoutStreamCountBuffering {搞定;私人集; }
    公共IPerformanceCounter ScaleoutErrorsTotal {搞定;私人集; }
    公共IPerformanceCounter ScaleoutErrorsPerSec {搞定;私人集; }
    公共IPerformanceCounter ScaleoutSendQueueLength {搞定;私人集; }
}内部类NoOpPerformanceCounter:IPerformanceCounter
{
    公共字符串CounterName
    {
        得到
        {
            返回的GetType()名称。
        }
    }
    众长递减()
    {
        返回0;
    }
    众长增量()
    {
        返回0;
    }
    众长IncrementBy(长值)
    {
        返回0;
    }
    众长RawValue
    {
        {返回0; }
        集合{}
    }
    公共无效关闭()
    {
    }
    公共无效RemoveInstance()
    {
    }
    公共CounterSample NextSample()
    {
        返回CounterSample.Empty;
    }
}

I have the following code in my Startup.SignalR.cs:

using Microsoft.AspNet.SignalR;
using Owin;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Admin
{
    public partial class Startup
    {
        public void ConfigureSignalR(IAppBuilder app)
        {
            var Config = new HubConfiguration()
            {
                EnableDetailedErrors = false,
                Resolver = new DefaultDependencyResolver()
            };

#if DEBUG
            Config.EnableDetailedErrors = true;
#endif
            // Any connection or hub wire up and configuration should go here
            app.MapSignalR();

            GlobalHost.Configuration.ConnectionTimeout = TimeSpan.FromSeconds(600);
        }
    }
}

During the initial loading of the application, everything goes fine, however when the thread is allowed to sleep (left for ~10min) the AppPool is recycled and the thread gets stuck on this line:

app.MapSignalR();

The IDE is stuck with the green arrow and This is the next statement to execute when this thread returns from the current function.. However I have no idea what the current function in this context is.

Attempting to inspect any local variables results in Cannot evaluate expression because a native frame is on top of the call stack. however the Call Stack shows: Admin.dll!Admin.Startup.ConfigureSignalR(Owin.IAppBuilder app) Line 25 as the top frame...

The code never recovers from this state and the AppPool has to be completely restarted by restarting the debugging session.

Anyone have any explaination for this scenario?

Additional information:After enabling Debug => Windows => Parrallel Stacks I see a more detailed Stack Trace:

[Managed to Native Transition]
mscorlib.dll!Microsoft.Win32.RegistryKey.OpenSubKey(string name, bool writable)
mscorlib.dll!Microsoft.Win32.RegistryKey.OpenSubKey(string name)
System.dll!System.Diagnostics.PerformanceCounterLib.FindCustomCategory(string category, out System.Diagnostics.PerformanceCounterCategoryType categoryType)
System.dll!System.Diagnostics.PerformanceCounterLib.IsCustomCategory(string machine, string category)
System.dll!System.Diagnostics.PerformanceCounter.InitializeImpl()
System.dll!System.Diagnostics.PerformanceCounter.PerformanceCounter(string categoryName, string counterName, string instanceName, bool readOnly)
Microsoft.AspNet.SignalR.Core.dll!Microsoft.AspNet.SignalR.Infrastructure.PerformanceCounterManager.LoadCounter(string categoryName, string counterName, string instanceName, bool isReadOnly)
Microsoft.AspNet.SignalR.Core.dll!Microsoft.AspNet.SignalR.Infrastructure.PerformanceCounterManager.LoadCounter(string categoryName, string counterName, bool isReadOnly)
Microsoft.AspNet.SignalR.Core.dll!Microsoft.AspNet.SignalR.Infrastructure.PerformanceCounterManager.SetCounterProperties()
Microsoft.AspNet.SignalR.Core.dll!Microsoft.AspNet.SignalR.Infrastructure.PerformanceCounterManager.Initialize(string instanceName, System.Threading.CancellationToken hostShutdownToken)
Microsoft.AspNet.SignalR.Core.dll!Microsoft.AspNet.SignalR.Hosting.HostDependencyResolverExtensions.InitializePerformanceCounters(Microsoft.AspNet.SignalR.IDependencyResolver resolver, string instanceName, System.Threading.CancellationToken hostShutdownToken)
Microsoft.AspNet.SignalR.Core.dll!Microsoft.AspNet.SignalR.Hosting.HostDependencyResolverExtensions.InitializeHost(Microsoft.AspNet.SignalR.IDependencyResolver resolver, string instanceName, System.Threading.CancellationToken hostShutdownToken)
Microsoft.AspNet.SignalR.Core.dll!Owin.OwinExtensions.UseSignalRMiddleware<Microsoft.AspNet.SignalR.Owin.Middleware.HubDispatcherMiddleware>(Owin.IAppBuilder builder, object[] args)
Microsoft.AspNet.SignalR.Core.dll!Owin.OwinExtensions.RunSignalR(Owin.IAppBuilder builder, Microsoft.AspNet.SignalR.HubConfiguration configuration)
Microsoft.AspNet.SignalR.Core.dll!Owin.OwinExtensions.MapSignalR.AnonymousMethod__0(Owin.IAppBuilder subApp)
Microsoft.Owin.dll!Owin.MapExtensions.Map(Owin.IAppBuilder app, Microsoft.Owin.PathString pathMatch, System.Action<Owin.IAppBuilder> configuration)
Microsoft.Owin.dll!Owin.MapExtensions.Map(Owin.IAppBuilder app, string pathMatch, System.Action<Owin.IAppBuilder> configuration)
Microsoft.AspNet.SignalR.Core.dll!Owin.OwinExtensions.MapSignalR(Owin.IAppBuilder builder, string path, Microsoft.AspNet.SignalR.HubConfiguration configuration)
Microsoft.AspNet.SignalR.Core.dll!Owin.OwinExtensions.MapSignalR(Owin.IAppBuilder builder, Microsoft.AspNet.SignalR.HubConfiguration configuration)
Microsoft.AspNet.SignalR.Core.dll!Owin.OwinExtensions.MapSignalR(Owin.IAppBuilder builder)
Admin.dll!Admin.Startup.ConfigureSignalR(Owin.IAppBuilder app) Line 25
解决方案

As mentioned by Pawel, I was able to resolve my issue with the use of a dummy Performance Counter as documented here: https://github.com/SignalR/SignalR/issues/3414

// Global.asmx
var tempCounterManager = new TempPerformanceCounterManager();
GlobalHost.DependencyResolver.Register(typeof (IPerformanceCounterManager), () => tempCounterManager);

[....]

// Helper Class
public class TempPerformanceCounterManager : IPerformanceCounterManager
{
    private readonly static PropertyInfo[] _counterProperties = GetCounterPropertyInfo();
    private readonly static IPerformanceCounter _noOpCounter = new NoOpPerformanceCounter();

    public TempPerformanceCounterManager()
    {
        foreach (var property in _counterProperties)
        {
            property.SetValue(this, new NoOpPerformanceCounter(), null);
        }
    }

    public void Initialize(string instanceName, CancellationToken hostShutdownToken)
    {
    }

    public IPerformanceCounter LoadCounter(string categoryName, string counterName, string instanceName, bool isReadOnly)
    {
        return _noOpCounter;
    }

    internal static PropertyInfo[] GetCounterPropertyInfo()
    {
        return typeof(TempPerformanceCounterManager)
            .GetProperties()
            .Where(p => p.PropertyType == typeof(IPerformanceCounter))
            .ToArray();
    }
    public IPerformanceCounter ConnectionsConnected { get; set; }
    public IPerformanceCounter ConnectionsReconnected { get; set; }
    public IPerformanceCounter ConnectionsDisconnected { get; set; }
    public IPerformanceCounter ConnectionsCurrentForeverFrame { get; private set; }
    public IPerformanceCounter ConnectionsCurrentLongPolling { get; private set; }
    public IPerformanceCounter ConnectionsCurrentServerSentEvents { get; private set; }
    public IPerformanceCounter ConnectionsCurrentWebSockets { get; private set; }
    public IPerformanceCounter ConnectionsCurrent { get; private set; }
    public IPerformanceCounter ConnectionMessagesReceivedTotal { get; private set; }
    public IPerformanceCounter ConnectionMessagesSentTotal { get; private set; }
    public IPerformanceCounter ConnectionMessagesReceivedPerSec { get; private set; }
    public IPerformanceCounter ConnectionMessagesSentPerSec { get; private set; }
    public IPerformanceCounter MessageBusMessagesReceivedTotal { get; private set; }
    public IPerformanceCounter MessageBusMessagesReceivedPerSec { get; private set; }
    public IPerformanceCounter ScaleoutMessageBusMessagesReceivedPerSec { get; private set; }
    public IPerformanceCounter MessageBusMessagesPublishedTotal { get; private set; }
    public IPerformanceCounter MessageBusMessagesPublishedPerSec { get; private set; }
    public IPerformanceCounter MessageBusSubscribersCurrent { get; private set; }
    public IPerformanceCounter MessageBusSubscribersTotal { get; private set; }
    public IPerformanceCounter MessageBusSubscribersPerSec { get; private set; }
    public IPerformanceCounter MessageBusAllocatedWorkers { get; private set; }
    public IPerformanceCounter MessageBusBusyWorkers { get; private set; }
    public IPerformanceCounter MessageBusTopicsCurrent { get; private set; }
    public IPerformanceCounter ErrorsAllTotal { get; private set; }
    public IPerformanceCounter ErrorsAllPerSec { get; private set; }
    public IPerformanceCounter ErrorsHubResolutionTotal { get; private set; }
    public IPerformanceCounter ErrorsHubResolutionPerSec { get; private set; }
    public IPerformanceCounter ErrorsHubInvocationTotal { get; private set; }
    public IPerformanceCounter ErrorsHubInvocationPerSec { get; private set; }
    public IPerformanceCounter ErrorsTransportTotal { get; private set; }
    public IPerformanceCounter ErrorsTransportPerSec { get; private set; }
    public IPerformanceCounter ScaleoutStreamCountTotal { get; private set; }
    public IPerformanceCounter ScaleoutStreamCountOpen { get; private set; }
    public IPerformanceCounter ScaleoutStreamCountBuffering { get; private set; }
    public IPerformanceCounter ScaleoutErrorsTotal { get; private set; }
    public IPerformanceCounter ScaleoutErrorsPerSec { get; private set; }
    public IPerformanceCounter ScaleoutSendQueueLength { get; private set; }
}

internal class NoOpPerformanceCounter : IPerformanceCounter
{
    public string CounterName
    {
        get
        {
            return GetType().Name;
        }
    }
    public long Decrement()
    {
        return 0;
    }
    public long Increment()
    {
        return 0;
    }
    public long IncrementBy(long value)
    {
        return 0;
    }
    public long RawValue
    {
        get { return 0; }
        set { }
    }
    public void Close()
    {
    }
    public void RemoveInstance()
    {
    }
    public CounterSample NextSample()
    {
        return CounterSample.Empty;
    }
}

这篇关于程序池循环后重新连接时MapSignalR MVC5挂起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-28 03:07