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().
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[");
}
}
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.
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.
Regards,
Gordon.
I had the same problem.
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.
You should solve your problem by removing the locks around the logging. The logging is done via Console.WriteLine
which is synchronized (and thread safe). You are possibly causing a deadlock through your own locking mechanism (though I can't verify without seeing the code).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With