В моем приложении SignalR Server я хотел регистрировать все трассировки SignalR в моем файле журнала log4net и следовал принятому ответу Дирка Воллмара в Как регистрировать сообщения трассировки с помощью log4net?.
Это работает: трассировки SignalR были записаны в моем файле журнала log4net. Когда подключается новый клиент SignalR, я вижу подробные журналы, которые мне нужны.
НО: после подключения нескольких клиентов к серверу, производящего некоторый трафик, все серверное приложение начинает зависать.
Когда я приостановил свое приложение в Visual Studio, я заметил много рабочих потоков:
Многие из этих рабочих потоков для System.Diagnostics.TraceSource.TraceEvent являются [Ожидание блокировки, принадлежащей Thread xyz]. Значит, они, кажется, запираются друг с другом?
Большой вопрос: как я могу регистрировать все события трассировки SignalR без блокировки?
Реализация: см. Log4netTraceListener.
Конфигурация в web.config:
<system.diagnostics>
<sources>
<source name="SignalR.SqlMessageBus">
<listeners>
<add name="SignalR-Log4netTraceListener" />
</listeners>
</source>
<source name="SignalR.ServiceBusMessageBus">
<listeners>
<add name="SignalR-Log4netTraceListener" />
</listeners>
</source>
<source name="SignalR.RedisMessageBus">
<listeners>
<add name="SignalR-Log4netTraceListener" />
</listeners>
</source>
<source name="SignalR.ScaleoutMessageBus">
<listeners>
<add name="SignalR-Log4netTraceListener" />
</listeners>
</source>
<source name="SignalR.Transports.WebSocketTransport">
<listeners>
<add name="SignalR-Log4netTraceListener" />
</listeners>
</source>
<source name="SignalR.Transports.ServerSentEventsTransport">
<listeners>
<add name="SignalR-Log4netTraceListener" />
</listeners>
</source>
<source name="SignalR.Transports.ForeverFrameTransport">
<listeners>
<add name="SignalR-Log4netTraceListener" />
</listeners>
</source>
<source name="SignalR.Transports.LongPollingTransport">
<listeners>
<add name="SignalR-Log4netTraceListener" />
</listeners>
</source>
<source name="SignalR.Transports.TransportHeartBeat">
<listeners>
<add name="SignalR-Log4netTraceListener" />
</listeners>
</source>
<source name="SignalR.ReflectedHubDescriptorProvider">
<listeners>
<add name="SignalR-Log4netTraceListener" />
</listeners>
</source>
</sources>
<switches>
<!--
================================
Set the trace verbosity level:
================================
0: Off Output no tracing and debugging messages.
1: Error Output error-handling messages.
2: Warning Output warnings and error-handling messages.
3: Info Output informational messages, warnings, and error-handling messages.
4: Verbose Output all debugging and tracing messages. -->
<add name="SignalRSwitch" value="Verbose" />
<!-- Note: Also hanging when using "Warning"-level -->
</switches>
<!--Specifies the trace writer for output-->
<sharedListeners>
<!--Listener for all events-->
<add name="SignalR-Log4netTraceListener" type="MySignalRServerApp.Log4netTraceListener, MySignalRServerApp" />
</sharedListeners>
<!-- Note: autoflush="false" makes no difference, still hanging -->
<trace autoflush="true" />
</system.diagnostics>