2012-04-13 14 views
7

Tengo muchas llamadas al servicio web (asychronous), en devolución de llamada, voy a trazar el resultado a Excel. Quiero sincronizar el método de trazado. Así que utilizo lo siguiente, sin embargo, desde que busco en Visual Studio, cada vez, el bloqueo (casillero) es exitoso, y hay muchos subprocesos ejecutando clearcommentIfany, plot. ¡No puedo entender por qué esto no funciona como esperaba! GraciasC# lock (mylocker) no funciona

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); 
    } 
} 
+0

Esta fuerza que ayuda a > http://stackoverflow.com/questions/5053172/why-does-the-lock-object-has-to-be-static – Sadaf

Respuesta

23

Sospecho que el problema aquí es que el bloqueo es un miembro de instancia en lugar de un miembro estático (nivel de tipo).

Suponiendo que cada subproceso tiene su propia instancia de la clase contenedora, también tendrá su propia instancia de su casillero, que no es lo que desea.

Pruebe esta declaración en su lugar:

private static readonly object locker = new object(); 

La inclusión de la palabra clave static ahora hace que esta instancia de objeto existir en el nivel de tipo, es decir, compartida a través de todas las instancias de la clase.

3

Deberá hacer el objeto static.

private static readonly object locker = new object(); 

Actualmente, cada instancia de la clase (y, por lo tanto, cada hilo) tiene su propia instancia del casillero.