Working with multiple threads is never easy and every now and then I keep running into seemingly bizarre issues and learn something new by fixing it..

This time it was about how to use the object lock statement (C# lock / VB.NET SyncLoc, .NET Monitor.Enter) properly.

See I had this method that was acting as a callback handler form a Delegate.BeginInvoke call. I had a dataset that was to be updated by multiple threads, so I had written code like following

DataSet _sharedDataset = new DataSet();

 

private void PostProcessingCallback(IAsyncResult ar)

{

    object Mycallbacklockobject = new object();

 

    lock (_sharedDataset)

    {

        //add a few rows to the dataset

    }

 

    //do some more processing

 

    lock (_sharedDataset)

    {

         //add another few rows to the dataset

    }

 

    //do some more processing

 

    //finally accept changes           
    _sharedDataset.AcceptChanges()

 }

This code seemingly worked for most of the time, but every now and then the method world throw some strange exception about the dataset being inconsistent when AcceptChages() was called.

It was only after a while I realized that it was a big mistake to release the dataset from the lock in between while other processing went on.

When you release the dataset in the middle of processing as above, there is no guarantee that the same thread will again get the lock even if it the method has not yet stopped executing!

So to fix the problem I had to change the code to the following.

DataSet _sharedDataset = new DataSet();

 

private void PostProcessingCallback(IAsyncResult ar)

{

    object Mycallbacklockobject = new object();

 

    lock (_sharedDataset)

    {

        //add a few rows to the dataset

   

        //do some more processing

 

        //add another few rows to the dataset

   

        //do some more processing

 

        //finally accept changes

        _sharedDataset.AcceptChanges();

    }
}


The idea is to keep the shared object under lock till all processing is over.I never go any exception again about the dataset being inconsistent.