19

I'm working with SignalR 1.1.2 version and Windsor Castle in an AspNet MVC 4 application. My problem is that this error message is showing up since I moved to the newer SignalR version.

"The requested Performance Counter is not a custom counter, it has to be initialized as ReadOnly."

in the line

    RouteTable.Routes.MapHubs();

This is the RegisterHubs class

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();
    }
}

I already tried a few things I've found in internet like:

lodctr /R
cd C:\Windows\Inf\.NETFramework
lodctr corperfmonsymbols.ini

But I'm still getting the same error message. Any ideas?

I'm using dotnet framework 4.5.

This is the stacktrace

at System.Diagnostics.PerformanceCounter.InitializeImpl()

Thanks!

UPDATE I'm adding the screenshots requested by Drew. enter image description here

enter image description here

enter image description here

polonskyg
  • 4,269
  • 9
  • 41
  • 93
  • Can you provide the entire stack trace, not just the bottom most entry? That'll help identify where in SignalR things are going wrong. – Drew Marsh Jul 09 '13 at 17:14
  • That's everything it has, nothing else. – polonskyg Jul 09 '13 at 18:39
  • That's not really possible. Can you take a screenshot of whatever you're looking at? Based on what you've told us so far I think you're seeing first chance exceptions while SignalR is attempting to connect up its perf counters. If you check out the SignalR source code where it initializes the perf counters you'll see the many reasons initialization might fail and how SignalR handles these gracefully. https://github.com/SignalR/SignalR/blob/master/src/Microsoft.AspNet.SignalR.Core/Infrastructure/PerformanceCounterManager.cs#L378 – Drew Marsh Jul 09 '13 at 20:46
  • @DrewMarsh screenshots were added to the question. – polonskyg Jul 10 '13 at 02:38

6 Answers6

28

So based on the information you've provided it is clear that these are first chance exceptions being thrown when SignalR is attempting to create the performance counters but doesn't have the rights to do so with the identity that the process is running under. You can safely ignore these exceptions, but you obviously won't get performance counter data.

If you want to create the performance counters you need to make sure the identity of your application belongs to the Performance Counter Users group when it's running. Either that or you need to use the utility application provided in the Microsoft ASP.NET SignalR Utilities NuGet package that allows you to create the counters out of band. Just install the package and run the command:

signalr ipc
Drew Marsh
  • 33,111
  • 3
  • 82
  • 100
  • 2
    It worked!! I had no idea of that package, thank you very much Drew! – polonskyg Jul 10 '13 at 13:11
  • 3
    This DOESN'T work for me Until I specified the full path to the "signalR.exe". Just hit the windows button and type "signalr.exe" to find it... In my case it's "C:\SVN\trunk\TestSln\packages\Microsoft.AspNet.SignalR.Utils.2.4.1\tools\net40\signalr.exe" Then I could install performance counters: PM> C:\SVN\trunk\TestSln\packages\Microsoft.AspNet.SignalR.Utils.2.4.1\tools\net40\signalr.exe ipc – jreichert Aug 27 '19 at 07:44
14

Drew Marsh's response, solved the problem for me, too. Here are additional details describing how to go about running the signalr command:


Use the package manager to install SignalR Utils:

  1. In VS: Tools -> Library Package Manager -> Package Manager Console
  2. From the command line, type:

    PM> Install-Package Microsoft.AspNet.SignalR.Utils

  3. Running the IDE as an Administrator, run:

    PM> signalr ipc

Administrator permissions are needed to do run the performance counters installation command (signalr ipc) - running without doing so results in this error:

Error: System.Security.SecurityException: Requested registry access is not allowed. at Microsoft.Win32.RegistryKey.OpenSubKey(String name, Boolean writable) at System.Diagnostics.PerformanceCounterLib.CreateRegistryEntry(String categoryName, PerformanceCounterCategoryType categoryType, CounterCreationDataCollec tion creationData, Boolean& iniRegistered) at System.Diagnostics.PerformanceCounterLib.RegisterCategory(String category Name, PerformanceCounterCategoryType categoryType, String categoryHelp, Counter CreationDataCollection creationData) at System.Diagnostics.PerformanceCounterCategory.Create(String categoryName, String categoryHelp, PerformanceCounterCategoryType categoryType, CounterCreationDataCollection counterData) at Microsoft.AspNet.SignalR.Utils.PerformanceCounterInstaller.InstallCounters()

   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
Community
  • 1
  • 1
CJBS
  • 15,147
  • 6
  • 86
  • 135
  • "The term 'signalr' is not recognized as the name of a cmdlet, function, script file, or operable program." after successfully installing the package. – UserControl Nov 05 '15 at 20:20
  • @UserControl It would seem that there was a problem installing signalr. What was the result of the `Install-Package` command? You might want to have a look at some of the cases documented here with regard to package installation options: http://stackoverflow.com/questions/13056329/nuget-is-not-recognized-but-other-nuget-commands-working – CJBS Nov 06 '15 at 05:53
  • The package installed successfully. For some reason IDE couldn't find the command. I had to find its location directory and run `signalr ipc` from there. – UserControl Nov 06 '15 at 08:30
  • For those search this: After you install the package, you have to restart Visual Studio and run it as Administrator by right click on the VS icon and click on "Run as Administrator". Then you can run the "signalr ipc" command from the Package Manager Console. – Ray Linder Jul 27 '16 at 19:33
3

Please note that if you follow the (correct) advice mentioned above and invoke 'signalr ipc' to install SignalR's custom counters, your application might inexplicably stop working altogether when running with the debugger. The issue is a bug in how the CLR deals with CultureInfo upon initialization. The problem exists at least in SignalR 2.2.0. The full explanation, and a couple of workarounds are discussed here: https://github.com/SignalR/SignalR/issues/3414

3

Here's a solution for devs who can't run with admin rights. Create the class below and add it to the DependencyResolver like this:

// Stop exception being thrown when trying to access performance counters
var dummyPerformanceCounterManager = new DummyPerformanceCounterManager();
GlobalHost.DependencyResolver.Register(
    typeof(IPerformanceCounterManager), 
    () =>dummyPerformanceCounterManager);

Here's the class that replaces the 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;
}
John Stewien
  • 1,046
  • 9
  • 5
  • For the DependencyResolver registration: `using Microsoft.AspNet.SignalR; using Microsoft.AspNet.SignalR.Infrastructure;` For the class: `using Microsoft.AspNet.SignalR.Infrastructure; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Threading;` – Nathan Feb 23 '21 at 14:44
0

Solved the problem. In my test or production server I don't have the IDE like Visual Studio which is installed in it. So that I stuck with the same error. At last I simply did the following steps:

Please do follow the below steps in the server that VS is installed

  • In VS: Tools -> NuGet Package Manager -> Package Manager Console From the command line, type:

  • PM> Install-Package Microsoft.AspNet.SignalR.Utils

  • Go to Packages -> Microsoft.AspNet.SignalR.Utils.2.2.3 -> Tools

  • Copy signalr.exe

Please do follow the below steps in the test or production server

  • Paste signalr.exe under bin -> debug folder and copy the path
  • Open Command Prompt in Administrator mode and change directory to the copied path
  • Type and run the command signalr.exe ipc

After running the above command successfully I have launched the application it worked fine. I have just posting this for others if they need it on the test environment.

0

If you dont want to use performance counters altogether, it is perfectly fine when your resolver returns "null" when it is asked for an IPerformanceCounterManager.

see in https://github.com/SignalR/SignalR/blob/master/src/Microsoft.AspNet.SignalR.Core/Hosting/HostDependencyResolverExtensions.cs

    private static void InitializePerformanceCounters(this IDependencyResolver resolver, string instanceName, CancellationToken hostShutdownToken)
    {
        var counters = resolver.Resolve<IPerformanceCounterManager>();
        if (counters != null)
        {
            counters.Initialize(instanceName, hostShutdownToken);
        }
    }

I just ran into the problem because ninject throws when its asked for an unconfigured dependency.