Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# lock(mylocker) not work

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);
    }
}
like image 452
toosensitive Avatar asked Apr 13 '12 15:04

toosensitive


1 Answers

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.

like image 94
Rob Levine Avatar answered Sep 29 '22 13:09

Rob Levine