I've run into a situation and I don't know if it can be resolved.
I've started adding a TraceSource
and trace statements to my multithreaded service, and I'm running into locks in the threads that process the trace methods in my code. This is causing the entire app to hang.
My service is configured to run within a console window for debugging purposes. I know this is related to the issue as I am also writing to a ConsoleTraceListener
.
This locking seems to occur between external code and an internal call to Console.ReadKey()
. As an example of the code and configuration, my application may make calls such as these within async methods:
class MyService : ServiceBase
{
static TraceSource trace = new TraceSource("mysource");
void asyncMethod1()
{
trace.TraceInformation("Some useful information.");
}
void asyncMethod2()
{
trace.TraceInformation("Some other useful information.");
}
/// other members and methods ...
}
The TraceSource
is defined in the app.config
file as
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
<system.diagnostics>
<trace autoflush="true" indentsize="4" useGlobalLock="true" />
<sources>
<source name="mysource" switchName="TraceSwitch" switchType="System.Diagnostics.SourceSwitch">
<listeners>
<add name="console" />
<add name="eventlog" />
<add name="logfile" />
</listeners>
</source>
</sources>
<sharedListeners>
<add name="console" type="System.Diagnostics.ConsoleTraceListener" initializeData="false" />
<add name="eventlog" type="System.Diagnostics.EventLogTraceListener" initializeData="EventSource">
<filter type="System.Diagnostics.EventTypeFilter" initializeData="Error"/>
</add>
<add name="logfile" type="System.Diagnostics.TextWriterTraceListener" initializeData="logfiles\errors.log">
<filter type="System.Diagnostics.EventTypeFilter" initializeData="Error"/>
</add>
</sharedListeners>
<switches>
<add name="TraceSwitch" value="Information" />
</switches>
</system.diagnostics>
</configuration>
REPRODUCING the issue
Once the app is started, the code in Program.Main(args[])
waits for a Console.ReadKey()
to stop the app.
static int Main(string[] args)
{
/// ...
MyService service = new MyService();
service.StartService();
Console.WriteLine("Press any key to exit application.");
Console.ReadKey(true);
///...
}
When I run the service in console, and using quickedit mode click or select with the mouse anywhere in the console window, the TraceSource
method calls lock up the rest of the application, until I hit a key which also stops the application.
Is there a way that I can prevent this console thread from locking the other threads? Or do I misinterpret what is happening here?
After I click in the console window to reproduce the issue, the call stack may look something like this:
THREAD 1
[Managed to Native Transition]
System.IO.__ConsoleStream.WriteFileNative
System.IO.__ConsoleStream.Write
System.IO.StreamWriter.Flush
System.IO.StreamWriter.Write
System.IO.TextWriter.SyncTextWriter.Write
System.Diagnostics.TextWriterTraceListener.Write
System.Diagnostics.TraceListener.WriteHeader
System.Diagnostics.TraceListener.TraceEvent
System.Diagnostics.TraceSource.TraceEvent
System.Diagnostics.TraceSource.TraceInformation
myservice.MyService.asyncMethod1 Line 202 C#
THREAD 2
System.Threading.Monitor.Enter
System.Diagnostics.TraceSource.TraceEvent
System.Diagnostics.TraceSource.TraceInformation
myservice.MyService.asyncMethod2 Line 134 C#