c# - example - signalr hub on event
El contador de rendimiento solicitado no es un contador personalizado, debe inicializarse como ReadOnly. "En RouteTable.Routes.MapHubs(); (5)
Estoy trabajando con la versión SignalR 1.1.2 y Windsor Castle en una aplicación AspNet MVC 4. Mi problema es que este mensaje de error aparece desde que me mudé a la versión más nueva de SignalR.
"The requested Performance Counter is not a custom counter, it has to be initialized as ReadOnly."
En la linea
RouteTable.Routes.MapHubs();
Esta es la clase RegisterHubs
public static class RegisterHubs
{
public static void Start()
{
var signalrDependencyContainer = new WindsorContainer().Install(new HubsInstaller());
var signalrDependency = new SignalrDependencyResolver(signalrDependencyContainer.Kernel);
GlobalHost.DependencyResolver = signalrDependency;
RouteTable.Routes.MapHubs();
}
}
Ya probé algunas cosas que he encontrado en internet como:
lodctr /R
cd C:/Windows/Inf/.NETFramework
lodctr corperfmonsymbols.ini
Pero sigo recibiendo el mismo mensaje de error. ¿Algunas ideas?
Estoy usando dotnet framework 4.5.
Este es el stacktrace.
at System.Diagnostics.PerformanceCounter.InitializeImpl()
¡Gracias!
ACTUALIZACIÓN Estoy agregando las capturas de pantalla solicitadas por Drew.
Aquí hay una solución para desarrolladores que no pueden correr con derechos de administrador. Cree la clase a continuación y agréguela a DependencyResolver de esta manera:
// Stop exception being thrown when trying to access performance counters
var dummyPerformanceCounterManager = new DummyPerformanceCounterManager();
GlobalHost.DependencyResolver.Register(
typeof(IPerformanceCounterManager),
() =>dummyPerformanceCounterManager);
Aquí está la clase que reemplaza al PerformanceCounterManager
public class DummyPerformanceCounterManager : IPerformanceCounterManager
{
private readonly static PropertyInfo[] _counterProperties = GetCounterPropertyInfo();
private readonly static IPerformanceCounter _noOpCounter = new NoOpPerformanceCounter();
public DummyPerformanceCounterManager()
{
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(DummyPerformanceCounterManager)
.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 => GetType().Name;
public long Decrement() => 0;
public long Increment() => 0;
public long IncrementBy(long value) => 0;
public long RawValue { get; set; } = 0;
public void Close() { }
public void RemoveInstance() { }
CounterSample IPerformanceCounter.NextSample() => CounterSample.Empty;
}
Por lo tanto, de acuerdo con la información que proporcionó, está claro que estas son excepciones de primera oportunidad cuando SignalR intenta crear los contadores de rendimiento pero no tiene los derechos para hacerlo con la identidad con la que se está ejecutando el proceso. Puede ignorar estas excepciones de forma segura, pero obviamente no obtendrá datos del contador de rendimiento.
Si desea crear los contadores de rendimiento, debe asegurarse de que la identidad de su aplicación pertenece al grupo de Usuarios del contador de rendimiento cuando se está ejecutando. O eso, o necesita usar la aplicación de utilidad provista en el paquete NuGet de Utilidades de Microsoft ASP.NET SignalR que le permite crear los contadores fuera de banda. Solo instala el paquete y ejecuta el comando:
signalr ipc
Resuelve el problema. En mi servidor de prueba o producción no tengo el IDE como Visual Studio que está instalado en él. Para que me quede con el mismo error. Por fin simplemente hice los siguientes pasos:
Por favor, siga los pasos a continuación en el servidor donde está instalado VS
En VS: Herramientas -> NuGet Package Manager -> Package Manager Console Desde la línea de comando, escriba:
PM>
Install-Package Microsoft.AspNet.SignalR.Utils
Vaya a Paquetes -> Microsoft.AspNet.SignalR.Utils.2.2.3 -> Herramientas
Copiar signalr.exe
Por favor, siga los pasos a continuación en el servidor de prueba o producción
- Pegue signalr.exe en bin -> depure la carpeta y copie la ruta
- Abra el símbolo del sistema en el modo Administrador y cambie el directorio a la ruta copiada
- Escribe y ejecuta el comando
signalr.exe ipc
Después de ejecutar el comando anterior con éxito, he lanzado la aplicación funcionó bien. Acabo de publicar esto para otros si lo necesitan en el entorno de prueba.
Tenga en cuenta que si sigue los consejos (correctos) mencionados anteriormente e invoca ''signalr ipc'' para instalar los contadores personalizados de SignalR, es posible que su aplicación deje de funcionar por completo cuando se ejecuta con el depurador. El problema es un error en la forma en que el CLR trata con CultureInfo en la inicialización. El problema existe al menos en SignalR 2.2.0. La explicación completa, y un par de soluciones se discuten aquí: https://github.com/SignalR/SignalR/issues/3414
La respuesta de Drew Marsh , también resolvió el problema para mí. Aquí hay detalles adicionales que describen cómo ejecutar el comando signalr
:
Utilice el administrador de paquetes para instalar SignalR Utils:
- En VS: Herramientas -> Library Package Manager -> Package Manager Console
Desde la línea de comando, escriba:
PM>
Install-Package Microsoft.AspNet.SignalR.Utils
Ejecutando el IDE como administrador, ejecute:
PM>
signalr ipc
Se necesitan permisos de administrador para ejecutar el comando de instalación de los contadores de rendimiento ( signalr ipc
). Si se ejecuta sin hacerlo, se produce este error:
Error: System.Security.SecurityException: el acceso al registro solicitado no está permitido. at Microsoft.Win32.RegistryKey.OpenSubKey (String, Boolean writeable) en System.Diagnostics.PerformanceCounterLib.CreateRegistryEntry (String categoryName PerformanceCounterCategoryType categoryType, String categoryHelp, Counter CreationDataCollection creationData) en System.Diagnostics.PerformanceCounterCategory.Create (String categoryName, String categoryPaceantePelazaciónPlacosPequeñoGratisCreativoPraquePrazaPlacerPlacerPlacerPacre en la empresaPersonalidadPlacas de recreoPersonal en el centro de la ciudad
at Microsoft.AspNet.SignalR.Utils.InstallPerformanceCountersCommand.Execute( String[] args) at Microsoft.AspNet.SignalR.Utils.Program.Main(String[] args) The Zone of the assembly that failed was: MyComputer