2012-03-29 19 views
18

Estamos utilizando una cola de bus de servicio en nuestro proyecto. Necesitamos una funcionalidad para eliminar todos los mensajes de la cola cuando el administrador decida borrar la cola. Busqué en la red pero no pude encontrar ninguna función que haga esto dentro de la clase QueueClient.Borrado de la cola del bus de servicio azul de una vez

¿Tengo que mostrar todos los mensajes uno por uno y luego marcarlos para borrar la cola o hay una manera mejor?

QueueClient queueClient = _messagingFactory.CreateQueueClient(
           queueName, ReceiveMode.PeekLock); 

BrokeredMessage brokeredMessage = queueClient.Receive(); 

while (brokeredMessage != null) 
{ 
    brokeredMessage.Complete(); 
    brokeredMessage = queueClient.Receive(); 
} 
+1

Recientemente me enfrenté al mismo problema, y ​​eliminar y volver a crear no era una opción, el bucle funciona, pero es lento, sin embargo, usando el miembro 'PrefetchCount' del' QueueClient' puede fácilmente agrupar varios miles de mensajes en un solo ida y vuelta, acelerando enormemente las cosas: http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.queueclient.prefetchcount.aspx – Necrolis

Respuesta

8

Utilizando el método Receive() dentro del bucle while como si hará que su código se ejecute de forma indefinida una vez que la cola está vacía, como el método Receive() estará esperando otro mensaje que aparezca en la cola.

Si desea que esto se ejecute automáticamente, intente con el método Peek().

Por ejemplo:

while (queueClient.Peek() != null) 
{ 
    var brokeredMessage = queueClient.Receive(); 
    brokeredMessage.Complete(); 
} 

Usted puede hacer esto de nuevo más simple con la ReceiveMode.ReceiveAndDelete como fue mencionado por Hocho.

+1

Algunas preocupaciones: (1) Peek se programará, el futuro los mensajes que reciben no causarán que su aplicación cuelgue a la espera de mensajes programados. (2) Cada Peek pasa al siguiente mensaje independientemente de su estado, por lo que si abandona el primer mensaje en lugar de Completar, el segundo Peek recibirá el 2 ° mensaje, pero el 2 ° Recibirá el 1 °. Esto hace que Peek se desplace de Receive en un mensaje y dejará un mensaje sin procesar al final de la cola para cada mensaje abandonado. –

+0

+1 @JustinJStark Al probar este código (es decir, sin procesamiento, solo recibir y completar) en una cola que no recibía mensajes nuevos, siempre no se borraba completamente la cola. Solo estaba borrando el 50-75% de los mensajes. No usaría este enfoque para borrar una cola. – Justin

2

Para Azure-ServiceBus-Queues hay un ReceiveBatch-method que le permite recibir un lote de n -mensajes en el momento. Combinado con ReceiveMode.ReceiveAndDelete puede borrar la cola de manera más eficiente.

Advertencia El número n de mensajes podría ser devuelto pero no está garantizada. También hay un límite para el tamaño del lote de mensajes de 256K.

5

Usando:

  • Tanto enfoque (de @ScottBrady y @participant)
  • Y la abstracción MessageReceiver

puede escribir un método que se vacía una cola bus de servicio o de un tema/suscripción:

MessageReceiver messageReceiver = ... 
while (messageReceiver.Peek() != null) 
{ 
    // Batch the receive operation 
    var brokeredMessages = messageReceiver.ReceiveBatch(300); 

    // Complete the messages 
    var completeTasks = brokeredMessages.Select(m => Task.Run(() => m.Complete())).ToArray(); 

    // Wait for the tasks to complete. 
    Task.WaitAll(completeTasks); 
} 
1

La manera más rápida de limpiar un Azure Serv iceBus Queue es establecer un muy corto DefaultMessageTimeToLive, espere unos segundos, intente recibir de la cola forzarlo para actualizar y restaurar el DefaultMessageTimeToLive inicial.

Puede hacerlo desde el portal o de código:

var namespaceManager = NamespaceManager.CreateFromConnectionString(connectionString); 
var queueDescription = _namespaceManager.GetQueue(queueName); 
var queueClient = QueueClient.CreateFromConnectionString(connectionString, queueName, ReceiveMode.ReceiveAndDelete); 

var dl = queueDescription.EnableDeadLetteringOnMessageExpiration; 
var ttl = queueDescription.DefaultMessageTimeToLive; 

queueDescription.EnableDeadLetteringOnMessageExpiration = false; 
queueDescription.DefaultMessageTimeToLive = TimeSpan.FromSeconds(1); 

Thread.Sleep(5000); 
var dumy = queueClient.ReceiveBatch(200, TimeSpan.FromSeconds(1)).ToArray(); 

queueDescription.EnableDeadLetteringOnMessageExpiration = dl; 
queueDescription.DefaultMessageTimeToLive = ttl; 
+0

Hola, Florent, No estoy seguro de si la API ha cambiado, pero acabo de probar esto en mi cola y no tuvo cambios. Los mismos mensajes en la cola antes y después. –

0

Hay una sencilla Clear() método para borrar toda la cola si está utilizando la biblioteca de WindowsAzure.Storage Nuget. Utilizo la clase Microsoft.Windows.Azure.Queue de esa biblioteca para administrar la cola. De lo contrario, puede acceder a través de su API per their documentation. No sé cuánto tiempo ha estado el método en la biblioteca de Azure y probablemente no existía cuando se formuló originalmente la pregunta, pero la API REST se remonta al menos desde 2014 por this Azure feedback post

El completo.código NET para borrar la cola con la biblioteca Azure es:

string connectionString = "YourAzureConnectionStringHere"; 
string queueName = "YourWebJobQueueName"; 
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString); 

// Create the queue client, then get a reference to queue 
CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient(); 
queue = queueClient.GetQueueReference(GetQueueName(queueName)); 

// Clear the entire queue 
queue.Clear(); 
0

Estoy teniendo buenos resultados utilizando una combinación de ReceiveAndDelete, PrefetchCount, ReceiveBatchAsync, y un simple lazo de la verdad en lugar de utilizar la ojeada. Ejemplo con MessagingFactory a continuación:

var receiverFactory = MessagingFactory.CreateFromConnectionString("ConnString"); 
var receiver = receiverFactory.CreateMessageReceiver("QName", ReceiveMode.ReceiveAndDelete); 
receiver.PrefetchCount = 300; 

bool loop = true; 
while (loop) 
{ 
    var messages = await receiver.ReceiveBatchAsync(300, TimeSpan.FromSeconds(1)); 
    loop = messages.Any(); 
} 

requiere el paquete Nuget WindowsAzure.ServiceBus Sólo.

Cuestiones relacionadas