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
Post a Comment