在一个多线程的C#控制台应用程序挂起不频繁使用Console.Writeline()或Console.Write时() [英] Infrequent hangs in a multi-threaded C# console application when using Console.Writeline() or Console.Write()
问题描述
我已经写了一个控制台应用程序,使得使用console.write和console.writeline的提供一些日志记录。该应用程序是用于通信异步beginacceptconnection()和的BeginRead()(插座)的服务器应用程序。偶尔我得到了它挂的报告,并从有限的调试,我可以做我能够看到正在Console.Writeline()或Console.write()的问题。
I have written a console application that makes use of console.write and console.writeline to provide some logging. The application is a server application that uses asynchronous beginacceptconnection() and beginread() ( Sockets ) for communication. Occasionally i get reports of it hanging and from the limited debug i can do i am able to see the problem being Console.Writeline() or Console.write().
被多线程我一直小心周围有日志类锁所以只有一个线程可以一次登录的消息时.....我已经抓到了挂我得到的是线程阻塞在锁和VS报告该控件传递到Console.Write,它是等待它回来....它从来不会。
Being multi-threaded I have been careful to have a lock around the logging class so only one thread can log a message at once.....when I've caught a hang all i get are threads blocking on the lock and VS reporting that the control has passed into Console.Write and it is waiting for it to come back....it never does.
一对夫妇的天前,我得到了一个故障,但在启动过程中这个时候....在没有非同步连接都尚未拉开序幕的另一份报告(主线程做产生一个线程,虽然启动),我被送到一个画面.....见下文。(我加了开始和结束的临界区线,以防止这一点,它没有)
A couple of days ago i got another report of a failure but this time during bootup....where no asynch connections have yet been kicked off( the main thread does spawn a thread to bootup though ) and I was sent a picture.....see below.( i added the begin and end critical section lines to prevent this and it did not )
// Logging Class
public class Logging
{
// Lock to make the logging class thread safe.
static readonly object _locker = new object();
public delegate void msgHandlerWriteLineDelegate(string msg, Color col);
public static event msgHandlerWriteLineDelegate themsgHandlerWriteLineDelegate;
public delegate void msgHandlerWriteDelegate(string msg, Color col);
public static event msgHandlerWriteDelegate themsgHandlerWriteDelegate;
public static void Write(string a, Color Col)
{
if (themsgHandlerWriteDelegate != null)
{
lock (_locker)
{
themsgHandlerWriteDelegate(a, Col);
}
}
}
public static void Write(string a)
{
if (themsgHandlerWriteDelegate != null)
{
lock (_locker)
{
themsgHandlerWriteDelegate(a, Color.Black);
}
}
}
public static void WriteLine(string a, Color Col)
{
if (themsgHandlerWriteLineDelegate != null)
{
lock (_locker)
{
themsgHandlerWriteLineDelegate(a, Col);
}
}
}
public static void WriteLine(string a)
{
if (themsgHandlerWriteLineDelegate != null)
{
lock (_locker)
{
themsgHandlerWriteLineDelegate(a, Color.Black);
}
}
}
// Console Methods That implement the delegates in my logging class.
public static void ConsoleWriteLine(string message, Color Col)
{
try
{
if (Col == Color.Black)
{
Console.ForegroundColor = ConsoleColor.Gray;
}
else
{
Console.ForegroundColor = (ConsoleColor)Enum.Parse(typeof(ConsoleColor), Col.Name);
}
Thread.BeginCriticalRegion();
Console.WriteLine(message);
Thread.EndCriticalRegion();
Console.ForegroundColor = ConsoleColor.Gray;
}
catch (ThreadAbortException ex)
{
Console.WriteLine("ThreadAbortException : " + ex.Message);
}
catch (Exception ex)
{
Console.WriteLine("Exception : " + ex.Message);
}
}
public static void ConsoleWrite(string message, Color Col)
{
try
{
if (Col == Color.Black)
{
Console.ForegroundColor = ConsoleColor.Gray;
}
else
{
Console.ForegroundColor = (ConsoleColor)Enum.Parse(typeof(ConsoleColor), Col.Name);
}
Thread.BeginCriticalRegion();
Console.Write(message);//**THIS IS WHERE IS HANGS...IT NEVER RETURNS **
Thread.EndCriticalRegion();
Console.ForegroundColor = ConsoleColor.Gray;
}
catch (ThreadAbortException ex)
{
Console.WriteLine("ThreadAbortException : " + ex.Message);
}
catch (Exception ex)
{
Console.WriteLine("Exception : " + ex.Message);
}
}
public static void ConsoleUpdate(string message)
{
try
{
Thread.BeginCriticalRegion();
Console.WriteLine(message);//**THIS IS WHERE IS HANGS...IT NEVER RETURNS **
Thread.EndCriticalRegion();
}
catch (ThreadAbortException ex)
{
Console.WriteLine("ThreadAbortException : " + ex.Message);
}
catch (Exception ex)
{
Console.WriteLine("Exception : " + ex.Message);
}
}
// The main method...subscribes to delegates and spawns a thread to boot HW..main thread then exits.
public static void Main()
{
Logging.themsgHandlerWriteDelegate += new Logging.msgHandlerWriteDelegate(ConsoleWrite);
Logging.themsgHandlerWriteLineDelegate += new Logging.msgHandlerWriteLineDelegate(ConsoleWriteLine);
Logging.themsgHandlerUpdateDelegate += new Logging.msgHandlerUpdateDelegate(ConsoleUpdate);
}
}
public class ClassOnOtherThread
{
// In a different class running on a different thread the following line occasionly invokes the error:
private void BootHw(string Resource, string Resource2)
{
Logging.Write("\t\t[");
}
}
我在MSDN的解读表明Console.WriteLine和控制台.WRITE是线程安全的,所以我实际上并不需要它周围的锁....我也无法相信微软的代码是错误的(;-)所以我猜测这是一些互动我的代码是做它创建。误差
My reading of the MSDN suggests Console.WriteLine and Console.Write are threadsafe and therefore i don't actually need a lock around it....i also can't believe it Microsoft's code is wrong(;-) and so I am guessing it is some interaction my code is doing which creates the error.
现在我的问题:我应该做些什么来防止Console.WriteLine和Console.Write被打断......这是我的猜测,这事中断...但我真的不知道!
Now my question : Should i be doing anything to prevent Console.WriteLine and Console.Write being interrupted?...it is my guess that something it interrupting it...but i don't really know that!!
任何帮助将我非常赞赏。
Any help would me very much appreciated.
问候,
戈登。
推荐答案
我有同样的问题。
我用 console.readkey()
在主线程,以防止在调试模式下关闭应用程序。
I was using console.readkey()
in main thread to prevent closing application in debug mode.
在我用一个无限循环我的问题解决了取代了它。
After I replaced it with an infinite loop my problem was solved.
这篇关于在一个多线程的C#控制台应用程序挂起不频繁使用Console.Writeline()或Console.Write时()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!