【发布时间】:2011-06-27 20:45:18
【问题描述】:
我编写了一个控制台应用程序,它使用 console.write 和 console.writeline 来提供一些日志记录。该应用程序是一个服务器应用程序,它使用异步 beginacceptconnection() 和 beginread() ( Sockets ) 进行通信。有时我会收到关于它挂起的报告,并且从有限的调试中我可以看到问题是 Console.Writeline() 或 Console.write()。
由于是多线程的,我一直小心地在日志记录类周围加锁,这样只有一个线程可以一次记录一条消息.....当我遇到挂起时,我得到的只是线程阻塞在锁上和 VS 报告控件已传递到 Console.Write 并且它正在等待它回来......它永远不会。
几天前,我收到了另一份失败报告,但这次是在启动过程中......尚未启动任何异步连接(虽然主线程确实产生了一个线程来启动)并且我收到了一个图片.....见下文。(我添加了开始和结束关键部分行以防止这种情况,但它没有)
// 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 和 Console.Write 是线程安全的,因此我实际上不需要锁定它....我也不敢相信微软的代码是错误的 (;-) 和所以我猜这是我的代码正在执行的一些交互导致错误。
现在我的问题:我应该做些什么来防止 Console.WriteLine 和 Console.Write 被打断吗?...我猜是它打断了它...但我真的不知道!!
非常感谢任何帮助。
问候,
戈登。
【问题讨论】:
-
我明天一回到办公室就发一些。
-
按Ctrl+S,瞬间挂机。
-
看到代码后:有很多(真的)可以去掉。我无法发现明显的错误,但 Begin/EndCrtiticalRegion 并不是有意的,也不是 Console.WriteLine() 所需要的。您的错误可能在套接字代码中。
-
是的,开始/结束临界区方法确实是我尝试修复它,但它没有工作。我仍然很困惑套接字代码如何阻止 console.writeline()
-
你有多确定是WriteLine挂了?
标签: c# console-application freeze console.writeline