1

Ich wurde beauftragt, die Leistung einer Worker-Rolle zu verbessern, die die Nachrichten aus der Warteschlange verarbeitet.Azure QueueClient MaxConcurrentCalls funktioniert nicht

Es queueclient.OnMessage Modell mit MaxConcurrentCalls Einstellung verwendet als 1.

Während der Verarbeitung gibt es Thread.Sleep für 5 Minuten, und das wird die Gesamtleistung dh behindern, wenn ich 10 Nachrichten in der Warteschlange habe es zumindest nehmen 45 Minuten, bevor es die 10. Nachricht

verarbeitet dachte ich, wenn ich MaxConcurrentCalls ändern ist, lassen 5 sagen dann sollte es 5 Meldungen parallel verarbeiten und die Wartezeit um 25 Minuten zu verkürzen, aber das funktioniert nicht :(

auch ich habe versucht, OnMessageAsync mit zu verwenden MaxConcurrentCalls aber kein Glück. unten ist das Snippet ich versuchte,

.OnMessageAsync(async (brokeredMessage) => 
{     
    bool shouldAbandon = false; 
    try 
    { 
     logger.Debug("Rcvd:" + brokeredMessage.SequenceNumber); 
     SomeTask(brokeredMessage); 
     await brokeredMessage.CompleteAsync(); 
    } 
    catch (Exception ex) 
    { 
     logger.Error(String.Format("An Error occured {0}", ex.ToString())); 
     shouldAbandon = true; 
    } 
    if (shouldAbandon) 
    { 
     await brokeredMessage.AbandonAsync(); 
    } 
}, new OnMessageOptions { AutoComplete = false, MaxConcurrentCalls = 10 }); 

private void SomeTask(BrokeredMessage bm) 
{    
    logger.Debug("id: " + bm.MessageId + "on thread: " + Thread.CurrentThread.ManagedThreadId); 
    Thread.Sleep(30 * 1000); 
    logger.Debug("seq: " + bm.SequenceNumber); 
    logger.Debug("body: " + bm.GetBody<string>()); 
} 

Letzte Option Ich denken kann, ist eine neue Aufgabe auf OnMessage Ereignis zu starten. Es gibt einige Dinge, auf die ich achten muss (sicherstellen, dass abgeschlossene Aufgaben aus dem Sammlungs-/Hauptthread entfernt werden und ein Objekt von BrokeredMessage übergeben werden, da BrokeredMessage entsorgt wird, so dass ich den Taskthread nicht verwenden kann) und ich habe Vernunft hat es auch getestet, aber ich bin nicht überzeugt, dass dies die beste Lösung ist.

+0

Vergessen zu erwähnen, größten Nachteil der Task-Ansatz, wenn etwas in der Verarbeitung fehlschlägt, werden wir die Nachricht verlieren, während standardmäßig Nachricht hätte in der Warteschlange sein könnte. – DShah

+0

Was ist der Zweck des Schlafes? Simulieren Sie einen langen Prozess? Haben Sie versucht, Ihre SomeTask-Funktion asynchron zu machen? – Thomas

+0

Ja @Thomas, Schlaf simuliert den lang andauernden Prozess. Ich habe versucht, Task von der SomeTask-Methode zurückzugeben, um es asynchron zu machen, aber das hat nicht funktioniert, weil der Code noch Sleep verwendet hat, aber dann stolpere ich über einen anderen Thread in C# Multi Threading (http://stackoverflow.com/questions/14177891/can- jemand-bitte-erklären-async-erwarten) und ich erkannte, ich brauche Task.Delay und das funktionierte wie erwartet – DShah

Antwort

1

ersetzen SomeTask Umsetzung mit den folgenden:

async Task SomeTask(BrokeredMessage bm) 
{ 
    logger.Debug("id: " + bm.MessageId + "on thread: " + Thread.CurrentThread.ManagedThreadId); 
    await Task.Delay(30 * 1000).ConfigureAwait(false); 
    logger.Debug("seq: " + bm.SequenceNumber); 
    logger.Debug("body: " + bm.GetBody<string>()); 
} 

Wenn Thread.Sleep mit async auf dem gleichen Thread gemischt wird (in diesem Fall), verursacht es Thread zu 'Stall' alle Aufgaben. Da es keine Benutzeroberfläche gibt, verwenden Sie lieber .ConfigureAwait(false) für die asynchrone Operation, damit der Scheduler verwalten kann, welcher Thread ausgeführt werden soll.

+0

Danke @Sean und Entschuldigung für die späte Antwort, wie ich weg war, aber das ist genau ich tat, bevor ich in den Urlaub ging und es hat funktioniert. Schlüssel war, Task.Delay anstelle von Thread.Sleep zu verwenden, das ich von http://stackoverflow.com/questions/14177891/can-somebody-please-explain-async-await realisierte. – DShah

+0

Alles gut. Ich bin froh, dass du es geschafft hast. –

Verwandte Themen