我在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);
}
}
}
在初始加载应用程序期间,一切都很顺利,但是当允许线程休眠(离开约10分钟)时,AppPool会被回收并且线程卡在这一行上:
app.MapSignalR();
IDE卡住了绿色箭头和This is the next statement to execute when this thread returns from the current function.
。但是我不知道在这种情况下current function
是什么。
尝试检查任何局部变量会导致Cannot evaluate expression because a native frame is on top of the call stack.
但是调用堆栈显示:Admin.dll!Admin.Startup.ConfigureSignalR(Owin.IAppBuilder app) Line 25
作为顶部框架......
代码永远不会从此状态恢复,并且必须通过重新启动调试会话来完全重新启动AppPool。
任何人都对这种情况有任何解释?
其他信息: 启用Debug =>之后Windows =>并行堆栈我看到更详细的堆栈跟踪:
[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
答案 0 :(得分:11)
此博客文章的另一个解决方案: http://www.zpqrtbnk.net/posts/appdomains-threads-cultureinfos-and-paracetamol
app.SanitizeThreadCulture();
public static void SanitizeThreadCulture(this IAppBuilder app)
{
var currentCulture = CultureInfo.CurrentCulture;
// at the top of any culture should be the invariant culture,
// find it doing an .Equals comparison ensure that we will
// find it and not loop endlessly
var invariantCulture = currentCulture;
while (invariantCulture.Equals(CultureInfo.InvariantCulture) == false)
invariantCulture = invariantCulture.Parent;
if (ReferenceEquals(invariantCulture, CultureInfo.InvariantCulture))
return;
var thread = Thread.CurrentThread;
thread.CurrentCulture = CultureInfo.GetCultureInfo(thread.CurrentCulture.Name);
thread.CurrentUICulture = CultureInfo.GetCultureInfo(thread.CurrentUICulture.Name);
}
答案 1 :(得分:5)
如Pawel所述,我能够通过使用虚拟性能计数器来解决我的问题,如下所示: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;
}
}
答案 2 :(得分:2)
我在这里找到了解决方案:github.com/SignalR/SignalR/issues/3414 剪片样本:
public void Configuration(IAppBuilder app)
{
var task = Task.Run(() => app.MapSignalR());
task.Wait(300);
//try again if it fails just to be sure ;)
if (task.IsCanceled) Task.Run(() => app.MapSignalR()).Wait(300);
}