C# 控制台在TraceSource方法中锁定的线程
我遇到了一种情况,不知道能否解决 我已经开始向我的多线程服务添加C# 控制台在TraceSource方法中锁定的线程,c#,.net,multithreading,deadlock,trace,C#,.net,Multithreading,Deadlock,Trace,我遇到了一种情况,不知道能否解决 我已经开始向我的多线程服务添加TraceSource和trace语句,并且在处理代码中的跟踪方法的线程中遇到锁。这将导致整个应用程序挂起 我的服务配置为在控制台窗口中运行,以进行调试。我知道这与问题有关,因为我也在给一个ConsoleTraceListener写信 此锁定似乎发生在外部代码和对Console.ReadKey()的内部调用之间。作为代码和配置的示例,我的应用程序可能会在异步方法中进行如下调用: class MyService : ServiceBa
TraceSource
和trace语句,并且在处理代码中的跟踪方法的线程中遇到锁。这将导致整个应用程序挂起
我的服务配置为在控制台窗口中运行,以进行调试。我知道这与问题有关,因为我也在给一个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>
当我在console中运行服务,并使用quickedit模式在console窗口中的任意位置单击或用鼠标选择时,TraceSource
方法调用会锁定应用程序的其余部分,直到我按下一个键,该键也会停止应用程序
有没有一种方法可以防止这个控制台线程锁定其他线程?还是我误解了这里发生的事情
在控制台窗口中单击以重现问题后,调用堆栈可能如下所示: 线程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#
作品:
当我在控制台中运行服务,并在控制台窗口中的任意位置单击鼠标时,TraceSource方法调用会锁定应用程序的其余部分,直到我按下一个键,该键也会停止应用程序
您是否尝试在控制台中打开quickedit,并使用鼠标突出显示某些字符
根据我们下面的对话,您上面的问题显示挂起的原因是,在QuickEdit模式/突出显示文本期间,所有线程的控制台输出都被挂起。这已在Visual Studio调试器中得到确认
要继续执行,请按Esc键或单击鼠标右键
作品:
我想知道你知道有没有办法防止这种行为
是的,吉姆·米希尔写道:
如果要禁用快速编辑模式,需要调用GetConsoleMode以获取当前模式。然后清除启用快速编辑的位
您可以找到有关的详细信息。部署后,应用程序在控制台中运行的唯一时间是跟踪确定需要调查的错误时。否则,它将作为服务运行,到目前为止,我还没有在该操作模式中看到这个锁定问题。但是如果可能的话,我真的很想解决这个问题,给我们的现场工程师少一个障碍。有几种方法是异步的,并行运行的。@MickyD他们是异步回调,比如与TcpListener或UdpClient异步方法一起使用的回调。无论如何,我保证它们是异步的,正如我在问题中发布的并行堆栈所证明的那样。你对我遇到的问题的解决有什么想法吗?@MickyD我无法在应用程序中发布数千行代码,但我觉得上面包含了相关信息。你在找什么特别的东西吗?@MickyD从并行堆栈中可以看到,锁定的代码是外部代码,我无法发布。我怀疑是这样的,谢谢。。。但我想知道你是否知道有什么方法可以防止这种行为。如果应用程序挂起的时间足够长,它将崩溃,这在本例中是不可取的。@khargoosh ya直到最后一条评论才知道您正在使用QuickEdit。很高兴我们最终到达了那里:)直到你试图复制它,我才意识到它是相关的!谢谢:-)
System.Threading.Monitor.Enter
System.Diagnostics.TraceSource.TraceEvent
System.Diagnostics.TraceSource.TraceInformation
myservice.MyService.asyncMethod2 Line 134 C#