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