Come scrive Stefano, asincrona non viene eseguito il codice in un thread. Fortunatamente, è possibile utilizzare TaskFactory.FromAsync con MessageQueue.BeginReceive /MessageQueue.EndReceive di ricevere messaggi in modo asincrono:
private async Task<Message> MyAsyncReceive()
{
MessageQueue queue=new MessageQueue();
...
var message=await Task.Factory.FromAsync<Message>(
queue.BeginReceive(),
queue.EndReceive);
return message;
}
Si dovrebbe notare però che non c'è una versione di BeginReceive che utilizza una transazione. Da documenti BeginReceive:
Non utilizzare la chiamata asincrona BeginReceive con le transazioni. Se si desidera eseguire un'operazione asincrona transazionale, chiamare BeginPeek e inserire la transazione e il metodo di ricezione (sincrono) all'interno del gestore eventi creato per l'operazione di visualizzazione.
Questo ha senso in quanto non vi è alcuna garanzia per quanto tempo è necessario attendere una risposta o quale thread gestirà la chiamata completata.
di utilizzare le transazioni si potrebbe scrivere qualcosa di simile:
private async Task<Message> MyAsyncReceive()
{
var queue=new MessageQueue();
var message=await Task.Factory.FromAsync<Message>(queue.BeginPeek(),queue.EndPeek);
using (var tx = new MessageQueueTransaction())
{
tx.Begin();
//Someone may have taken the last message, don't wait forever
//Use a smaller timeout if the queue is local
message=queue.Receive(TimeSpan.FromSeconds(1), tx);
//Process the results inside a transaction
tx.Commit();
}
return message;
}
UPDATE
Come Rob ha sottolineato, il codice originale utilizzato il message
tornato da Peek
, che può aver cambiato tra Peek
e Receive
. In questo caso il secondo messaggio verrà perso.
C'è comunque una possibilità di blocco, se un altro client legge l'ultimo messaggio in coda. Per evitare ciò, Receive
dovrebbe avere un piccolo timeout.
fonte
2013-04-19 12:37:58
Il codice genera avvisi? Hai letto quello che dicono e hai cercato di capirli? – svick
Cerca nell'elenco dei tuoi errori, vedrai "Questo metodo asincrono manca di 'attendi' agli operatori e verrà eseguito in modo sincrono" –
Questa non è una domanda localizzata -inddice, ci sono molte domande simili in SO dove la gente pensa che 'async' in qualche modo rende il loro metodo eseguito in modo asincrono –