C#- Make sure the mutex, monito or semaphore, if used, are released properly.
Note: A semaphore with a capacity of one is similar to mutex or lock. Semaphore is thread-agnostic because it has no owner. Any thread can call release a semaphore, but with lock and mutex, only the thread that acquired the resource can release it.
C# example- Below Logger class covers using lock and monitor, releasing monitor and protecting only the resource being shared across threads.
class Logger
{
public string FilePath { get; set; }
private StreamWriter m_objStreamWriter = null;
private object m_objLocker;
public Logger()
{
m_objLocker=new object();
FilePath = @"d:\log.txt";
}
public bool Open()
{
bool blnStatus = false;
try
{
m_objStreamWriter = new StreamWriter(FilePath, true);
blnStatus = true;
}
catch (Exception objEx)
{
Console.WriteLine(objEx.StackTrace);
}
finally
{
}
return blnStatus;
}
public bool Close()
{
bool blnStatus = false;
try
{
if (m_objStreamWriter != null)
{
m_objStreamWriter.Close();
blnStatus = true;
}
}
catch (Exception objEx)
{
Console.WriteLine(objEx.StackTrace);
}
finally
{
}
return blnStatus;
}
//make sure Open is called before calling WriteToFile
//make sure Close is called once all logging is done
public bool WriteToFile(string strMessage)
{
bool blnStatus = false;
if (strMessage != string.Empty && strMessage != null)
{
try
{
lock (m_objLocker)
{
if (m_objStreamWriter != null)
{
//logs only the time and not the date
m_objStreamWriter.WriteLine(
DateTime.Now.TimeOfDay
+ " - "
+ strMessage
);
blnStatus = true;
}
}
}
catch (Exception objEx)
{
//use messagebox if winforms application
Console.WriteLine(objEx.StackTrace);
}
finally
{
}
}
return blnStatus;
}
//make sure the StreamWriter is closed
//make sure thr Monitor is exit
public bool WriteToFile_Local(string strMessage)
{
bool blnStatus = false;
StreamWriter objStreamWriter = null;
if (strMessage != string.Empty && strMessage != null)
{
try
{
Monitor.Enter(m_objLocker);
objStreamWriter = new StreamWriter(FilePath,
true);
//logs only the time and not the date
objStreamWriter.WriteLine(
DateTime.Now.TimeOfDay + " - " + strMessage
);
objStreamWriter.Close();
Monitor.Exit(m_objLocker);
blnStatus = true;
}
catch (Exception objEx)
{
//use messagebox if winforms application
Console.WriteLine(objEx.StackTrace);
if (objStreamWriter != null)
{
objStreamWriter.Close();
}
Monitor.Exit(m_objLocker);
}
finally
{
}
}
return blnStatus;
}
//exception has to be handled by the caller
//can not be unit tested using UnitTestingTool class
public void WriteToFile_Local_Using(string strMessage)
{
StreamWriter objStreamWriter = null;
if (strMessage != string.Empty && strMessage != null)
{
//private member variable
lock (m_objLocker)
{
using (objStreamWriter =
new StreamWriter(FilePath, true))
{
//logs only the time and not the date
objStreamWriter.WriteLine(
DateTime.Now.TimeOfDay + " - " +
strMessage
);
}
}
}
}
}
Rule: Write thread safe code if your application is multi threaded.
Rule: Protecting only the resource being shared across threads or processes.
Rule: Releasing the mutex, monitor or semaphore if used.
No comments:
Post a Comment