c# - MessageQueue and Async / Await -


i want receive message in async method! , freezing ui

    public async void processmessages()     {         messagequeue mymessagequeue = new messagequeue(@".\private$\mytransactionalqueue");         mymessagequeue.formatter = new xmlmessageformatter(new type[] { typeof(string) });          while (true)         {             messagequeuetransaction messagequeuetransaction = new messagequeuetransaction();             messagequeuetransaction.begin();              containerror = false;             processpanel.setwaiting();              string body = mymessagequeue.receive(messagequeuetransaction).body.tostring();              //do process body string.              messagequeuetransaction.commit();         }     } 

i calling method regular method , nos working! code used work when using backgroundworkers instead of async/await

ideas?

as stephen writes, async doesn't run code in thread. fortunately, can use taskfactory.fromasync messagequeue.beginreceive/messagequeue.endreceive receive messages asynchronously:

    private  async task<message> myasyncreceive()     {         messagequeue queue=new messagequeue();         ...         var message=await task.factory.fromasync<message>(                            queue.beginreceive(),                            queue.endreceive);          return message;      } 

you should note though there isn't version of beginreceive uses transaction. beginreceive's docs:

do not use asynchronous call beginreceive transactions. if want perform transactional asynchronous operation, call beginpeek, , put transaction , (synchronous) receive method within event handler create peek operation.

this makes sense there no guarantee how long have wait response or thread handle completed call.

to use transactions write this:

    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 last message, don't wait forever             //use smaller timeout if queue local             message=queue.receive(timespan.fromseconds(1), tx);             //process results inside transaction             tx.commit();         }         return message;     } 

update

as rob pointed out, original code used message returned peek, may have changed between peek , receive. in case second message lost.

there's still chance of blocking though, if client reads last message in queue. prevent this, receive should have small timeout.


Comments

Popular posts from this blog

node.js - Bad Request - node js ajax post -

Why does Ruby on Rails generate add a blank line to the end of a file? -

keyboard - Smiles and long press feature in Android -