c# - Volatile IEnlistmentNotification and TransactionScope.AsyncFlowEnabled = true -


apart .net 4.5.1 there new option on transactionscope enables use async flow. allows write following client code

using(var txt = new transactionscope(..., transactionscopeasyncflowoption.enabled) {    await sender.sendasync(); } 

so far good. when need implement volatile ienlistmentnotification i'm struggling that. let's imagine following scenario, assumption: underlying infrastructure async bottom top

public class messagesender : isendmessages {     public async task sendasync(transportmessage message, sendoptions options)     {         await sender.sendasync(message);     } } 

so want achieve introduce volatile ienlistmentnotification this:

internal class sendresourcemanager : ienlistmentnotification {     private readonly func<task> oncommit;      public sendresourcemanager(func<task> oncommit)     {         this.oncommit = oncommit;     }      public void prepare(preparingenlistment preparingenlistment)     {         preparingenlistment.prepared();     }      public void commit(enlistment enlistment)     {         await this.oncommit();         enlistment.done();     }      public void rollback(enlistment enlistment)     {         enlistment.done();     }      public void indoubt(enlistment enlistment)     {         enlistment.done();     } } 

and new sender

public class messagesender : isendmessages {     public async task sendasync(transportmessage message, sendoptions options)     {         // dirty: let's assume transaction.current never null         transaction.current.enlistvolatile(new sendresourcemanager(async () => { await sender.sendasync(message) }));     } } 

note: of course code doesn't compile. require me declare commit method async void. aweful.

so question is: how can write enlistment can internally await asynchronous operation?

as long enlistvolatile isn't heavy cpu bound time consuming operation, can create thin task based wrapper on enlistvolatile using task.fromresult:

public static class transcationextensions {     public static task enlistvolatileasync(this transaction transaction,                                             ienlistmentnotification                                             enlistmentnotification,                                             enlistmentoptions enlistmentoptions)     {         return task.fromresult(transaction.enlistvolatile                                            (enlistmentnotification,                                              enlistmentoptions));     } } 

and consume inside method:

public class messagesender : isendmessages {     public task sendasync(transportmessage message, sendoptions options)     {         return transaction.current.enlistvolatileasync                (new sendresourcemanager(async () =>                                         { await sender.sendasync(message) }));     } } 

which can awaited higher in callstack:

messagesender sender = new messagesender(); await sender.sendasync(message, options); 

Comments

Popular posts from this blog

ruby on rails - RuntimeError: Circular dependency detected while autoloading constant - ActiveAdmin.register Role -

c++ - OpenMP unpredictable overhead -

javascript - Wordpress slider, not displayed 100% width -