2012-04-04 30 views
33

¿Cuáles son las diferencias entre ConcurrentQueue y BlockingCollection en .Net?¿Cuáles son las diferencias entre ConcurrentQueue y BlockingCollection en .Net?

¿Por qué BlockingCollection es el mejor para la operación productor-consumidor cuando se puede hacer a través de ConcurrentQueue? ¿Debo mejorar algo en el siguiente código?

MessageSlotMachineGameStartOrAndStatusUpdate msg; 

while (!aCancellationToken.IsCancellationRequested) 
{ 
    try 
    { 
     this.isStillConsumingMsg = true; 
     Boolean takeResult = this.msgQueue.TryTake(out msg, this.msgConsumeTimeOut, aCancellationToken); 
     if (takeResult) 
     { 
      if (msg != null) 
      { 
       this.ProcessMessage(msg); 
      } 
     } 
     else 
     { 
      break; 
     } 
    } 
    catch (OperationCanceledException err) 
    { 
     EngineManager.AddExceptionLog(err, "Signal Operation Canceled"); 
    } 
    catch (Exception err) 
    { 
     EngineManager.AddExceptionLog(err, "Signal exception"); 
    } 
    finally 
    { 
     this.isStillConsumingMsg = false; 
    } 
} 

Respuesta

35

BlockingCollection tiene un método Take que bloquearía el consumidor si no hay nada para tomar, y esperar por un lado del productor de proporcionar un elemento. ConcurrentQueue carece de dicho método; si está vacío, el consumidor debería manejar la espera, y el productor debería proporcionar una notificación no vacía.

+0

me puede dar una muestra de cómo se puede hacer la notificación. –

+1

@WAPGuy Puede usar un ['AutoResetEvent'] (http://msdn.microsoft.com/en-us/library/system.threading.autoresetevent.aspx). Siga el enlace y desplácese hacia abajo para ver un ejemplo de cómo se usa. – dasblinkenlight

+0

¿está bien, cuando señala a WaitHandle? inmediatamente cuando está vacío o después de un tiempo de espera dado en el método Take? –

Cuestiones relacionadas