19

I have many web service call (asychronous), in callback, I will plot result to Excel. I want to synchronize the plot method. So I use the following, however, from I track down in Visual Studio, every time, lock(locker) is successful, and there are many threads running clearcommentIfany, plot. I can't figure out why this is not working as expected! Thanks

private readonly object locker = new object();

void ProcessPlot()
{
    lock (locker)
    {
        Debug.WriteLine("currentThreadID: " + Thread.CurrentThread.ManagedThreadId);
        //Helper.Dispatcher.Invoke(new AddClearCommentDelegate(ClearCommentIfAny));
        ClearCommentIfAny();

        if (Response.status != Status.COMPLETE)
        {
            ErrorMessage = ManipulateStatusMsg(Response);
            //Helper.Dispatcher.Invoke(new AddClearCommentDelegate(AddCommentToCell));
            AddCommentToCell();
        }
        else // COMPLETE
        {
            // TODO: Convert this into factory pattern
            Debug.WriteLine("ReportBuilder.Dispatcher's address " + Helper.GetAddress(Helper.Dispatcher));
            //Helper.Dispatcher.Invoke(new PlotDelegate(Plot), Response);
            Plot(Response);
        }               
    } 
}

public void DataRequestJobFinished(DataRequestResponse response)
{
    try
    {
        if (Request.IsRequestCancelled)
        {
            Request.FormulaCell.Dispose();
            return;
        }

        Response = response;

        //if (response.status != Status.COMPLETE)
        //{
        //    ErrorMessage = ManipulateStatusMsg(response);
        //}
        //else // COMPLETE
        //{
        //    // TODO: Convert this into factory pattern
        //    PlotDelegate plotDelegate = Plot;
        //    Debug.WriteLine("ReportBuilder.Dispatcher's address " + Helper.GetAddress(Helper.Dispatcher));
        //    Helper.Dispatcher.Invoke(plotDelegate, response);
        //    //Plot(response);                 
        //}
        var t = new Thread(ProcessPlot);
        t.Start();
        //ProcessPlot();
    }
    catch (Exception e)
    {
        ErrorMessage = e.Message;
        MIMICShared.Helper.LogError(e);
    }
    finally
    {
        //TODO: PutReportBuilderInQueue(this);
        ReadyForPlot = true;
        //Request.FormulaCell.Dispose(); move this after plot
        UnityContainer.Resolve<IEventAggregator>().GetEvent<DataRefreshEvent>().Publish(ID);
    }
}
John H
  • 14,422
  • 4
  • 41
  • 74
toosensitive
  • 2,335
  • 7
  • 46
  • 88
  • This might Helps you > http://stackoverflow.com/questions/5053172/why-does-the-lock-object-has-to-be-static – Sadaf Apr 13 '12 at 15:23

1 Answers1

43

I suspect your problem here is that your lock is an instance member rather than a static (type level) member.

Assuming that each thread has its own instance of the containing class, then it'll also have its own instance of your locker - which is not what you want.

Try this declaration instead:

private static readonly object locker = new object();

The inclusion of the static keyword now makes this object instance exist at the type level, i.e. shared across all instances of your class.

Rob Levine
  • 40,328
  • 13
  • 85
  • 111