I have the following class which tries to act as a simple asynchronous operation :
public class AsyncLineWriter
{
private delegate void SynchronousWriteLineDelegate(string message);
private SynchronousWriteLineDelegate DoWriteLine;
private void SynchronousWriteLine(string message)
{
Console.WriteLine(message);
}
public AsyncLineWriter()
{
DoWriteLine = new SynchronousWriteLineDelegate(SynchronousWriteLine);
public IAsyncResult BeginWriteLine(string message, AsyncCallback callback, object state)
{
return DoWriteLine.BeginInvoke(message,callback,state);
}
public void EndWriteLine(IAsyncResult asyncResult)
{
DoWriteLine.EndInvoke(asyncResult);
}
}
The following unit test is intermittently failing, but I don’t understand where the race condition is:
[TestMethod]
public void Callback_is_called()
{
// Arrange
AsyncLineWriter lineWriter = new AsyncLineWriter();
object state = new object();
object callbackState = null;
AsyncCallback callback = (r) =>
{
callbackState = r.AsyncState;
};
// Act
IAsyncResult asyncResult = lineWriter.BeginWriteLine("test", callback, state);
lineWriter.EndWriteLine(asyncResult);
// Assert
Assert.AreSame(state, callbackState);
}
In this pattern, the callback is run on a thread pool thread and you are supposed to call
EndInvokefrom within the callback.EndInvokedoesn’t wait for the callback to complete ( because this would cause a deadlock ), so you have a race between the callback and your test method.EDIT: The wait handle can be set before the callback has completed too. Try this: