控制台锁定在 TraceSource 方法中的线程
Threads locked in TraceSource methods by Console
我运行遇到了一个情况,不知道能否解决。
我已经开始向我的多线程服务添加 TraceSource
和跟踪语句,并且我 运行 锁定处理代码中跟踪方法的线程。这导致整个应用程序挂起。
出于调试目的,我的服务在控制台 window 中配置为 运行。我知道这与问题有关,因为我也在写信给 ConsoleTraceListener
.
这种锁定似乎发生在外部代码和对 Console.ReadKey()
的内部调用之间。作为代码和配置的示例,我的应用程序可能会在异步方法中进行如下调用:
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 ...
}
TraceSource
在app.config
文件中定义为
<?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>
重现问题
应用程序启动后,Program.Main(args[])
中的代码等待 Console.ReadKey()
停止应用程序。
static int Main(string[] args)
{
/// ...
MyService service = new MyService();
service.StartService();
Console.WriteLine("Press any key to exit application.");
Console.ReadKey(true);
///...
}
当我 运行 控制台中的服务,并使用 quickedit 模式单击或 select 鼠标在控制台 window 的任意位置时, TraceSource
方法调用锁定启动应用程序的其余部分,直到我按下一个也停止应用程序的键。
有什么方法可以防止此控制台线程锁定其他线程?还是我误解了这里发生的事情?
在我点击控制台 window 重现问题后,调用堆栈可能如下所示:
线程 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#
线程 2
System.Threading.Monitor.Enter
System.Diagnostics.TraceSource.TraceEvent
System.Diagnostics.TraceSource.TraceInformation
myservice.MyService.asyncMethod2 Line 134 C#
OP:
When I run the service in console, and click 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.
Would you try turning on quickedit in your console, and use the mouse to highlight some characters?
根据我们在上述问题下方的对话,它似乎挂起的原因是在 QuickEdit mode/highlighting 文本期间,所有线程的控制台输出都已暂停。这在 Visual Studio 调试器中得到了确认。
要继续执行,请按 Esc 或单击 鼠标右键。
OP:
I was wondering do you know if there was a way to prevent this behaviour
是的,吉姆米歇尔写道:
If you want to disable quick edit mode, you need to call GetConsoleMode to get the current mode. Then clear the bit that enables quick edit
您可以找到有关 Jim's answer here 的更多信息。
我运行遇到了一个情况,不知道能否解决。
我已经开始向我的多线程服务添加 TraceSource
和跟踪语句,并且我 运行 锁定处理代码中跟踪方法的线程。这导致整个应用程序挂起。
出于调试目的,我的服务在控制台 window 中配置为 运行。我知道这与问题有关,因为我也在写信给 ConsoleTraceListener
.
这种锁定似乎发生在外部代码和对 Console.ReadKey()
的内部调用之间。作为代码和配置的示例,我的应用程序可能会在异步方法中进行如下调用:
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 ...
}
TraceSource
在app.config
文件中定义为
<?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>
重现问题
应用程序启动后,Program.Main(args[])
中的代码等待 Console.ReadKey()
停止应用程序。
static int Main(string[] args)
{
/// ...
MyService service = new MyService();
service.StartService();
Console.WriteLine("Press any key to exit application.");
Console.ReadKey(true);
///...
}
当我 运行 控制台中的服务,并使用 quickedit 模式单击或 select 鼠标在控制台 window 的任意位置时, TraceSource
方法调用锁定启动应用程序的其余部分,直到我按下一个也停止应用程序的键。
有什么方法可以防止此控制台线程锁定其他线程?还是我误解了这里发生的事情?
在我点击控制台 window 重现问题后,调用堆栈可能如下所示:
线程 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#
线程 2
System.Threading.Monitor.Enter
System.Diagnostics.TraceSource.TraceEvent
System.Diagnostics.TraceSource.TraceInformation
myservice.MyService.asyncMethod2 Line 134 C#
OP:
When I run the service in console, and click 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.
Would you try turning on quickedit in your console, and use the mouse to highlight some characters?
根据我们在上述问题下方的对话,它似乎挂起的原因是在 QuickEdit mode/highlighting 文本期间,所有线程的控制台输出都已暂停。这在 Visual Studio 调试器中得到了确认。
要继续执行,请按 Esc 或单击 鼠标右键。
OP:
I was wondering do you know if there was a way to prevent this behaviour
是的,吉姆米歇尔写道:
If you want to disable quick edit mode, you need to call GetConsoleMode to get the current mode. Then clear the bit that enables quick edit
您可以找到有关 Jim's answer here 的更多信息。