Tuesday, November 2, 2010

Thread safe destructible event firing class in C#

Programmer Question

Dear Fellow Members,



Recently, I was asked to implement a class as part of a selection process. I did the program as requested. However, I failed in the test. I am really curious to know what is wrong in my solution. Any help is much appreciated. The question and my solution are given below



Question:



Implement a thread safe class which fires an event every second from construction. There need to be a function for finding the seconds elapsed. This class has to implement IDisposable and any calls to seconds elapsed function after calling dispose should fail.



My solution:



namespace TimeCounter
{
public delegate void SecondsElapsedHandler(object o, EventArgs e);
///
/// Summary description for SecondCounter
///

public class SecondCounter : IDisposable
{
private volatile int nSecondsElapsed;
Timer myTimer;
private readonly object EventLock = new object();
private SecondsElapsedHandler secondsHandler;
public SecondCounter()
{
nSecondsElapsed = 0;
myTimer = new Timer();
myTimer.Elapsed += new ElapsedEventHandler(OneSecondElapsed);
myTimer.Interval = 1000;
myTimer.AutoReset = false;
myTimer.Start();
}

public void OneSecondElapsed(object source, ElapsedEventArgs e)
{
try
{
SecondsElapsedHandler handlerCopy;
lock (EventLock)
{
handlerCopy = secondsHandler;
nSecondsElapsed++;

}
if (secondsHandler != null)
{
secondsHandler(this, e);
}
}
catch (Exception exp)
{
Console.WriteLine("Exception thrown from SecondCounter OneSecondElapsed " + exp.Message);
}
finally
{
if (myTimer != null)
{
myTimer.Enabled = true;
}
}
}

public event SecondsElapsedHandler AnotherSecondElapsed
{
add
{
lock (EventLock)
{
secondsHandler += value;
}
}
remove
{
lock (EventLock)
{
secondsHandler -= value;
}

}
}

public int SecondsElapsed()
{
if (this.IsDisposed)
{
throw new ObjectDisposedException("SecondCounter");
}
return nSecondsElapsed;

}

private bool IsDisposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool Disposing)
{
if (!IsDisposed)
{
if (Disposing)
{

}
if (myTimer != null)
{
myTimer.Dispose();
}

}
secondsHandler = null;
IsDisposed = true;

}
~SecondCounter()
{
Dispose(false);
}
}
}


Find the answer here

No comments:

Post a Comment

LinkWithin

Related Posts with Thumbnails