c# - Refactor to remove Taks.Run from my code -
i wrote following code
public void save() { while (this.isasyncinprocess) thread.sleep(100); this.customer.ordercount = this.orders.count(); this.customer.ordertotal = this.orders.sum(o => x.total); this.customerrepo.save(); } public async task loadasync() { this.isasyncinprocess = true; this.customer = await this.customerrepo.getcustomerasync(...); this.orders = await this.customerrepo.getordersasync(...); this.isasyncinprocess = false; } now had classical deadlock because, after this.orders completed, wait gui thread resume in order set this.isasyncinprocess false. however, gui thread busy inside save()
now refactored loadasync
public async task loadasync() { await task.run(async () => { this.isasyncinprocess = true; this.customer = await this.customerrepo.getcustomerasync(...); this.orders = await this.customerrepo.getordersasync(...); this.isasyncinprocess = false; }); } i can't refactor save saveasync compability reasons.
is there better way achive this, without using task.run?
you can use async locking. if can't change signiture of save can proxy async local function.
static semaphoreslim sem = new semaphoreslim(1,1); public void save() { saveasync(); public async task saveasync() { await sem.waitasync(); try{ this.customer.ordercount = this.orders.count(); this.customer.ordertotal = this.orders.sum(o => x.total); this.customerrepo.save(); }finally{ sem.release(); } } } public async task loadasync() { await sem.waitasync(); try{ this.customer = await this.customerrepo.getcustomerasync(...); this.orders = await this.customerrepo.getordersasync(...); }finally{ sem.release(); } } or better create own async lock
static semaphoreslim sem = new semaphoreslim(1,1); public static async task<idisposable> lockasync(){ await sem.waitasync(); return disposable.create(()=>sem.release()); } public void save() { saveasync(); public async task saveasync() { using(await lockasync()){ this.customer.ordercount = this.orders.count(); this.customer.ordertotal = this.orders.sum(o => x.total); this.customerrepo.save(); } } } public async task loadasync() { using(await lockasync()){ this.customer = await this.customerrepo.getcustomerasync(...); this.orders = await this.customerrepo.getordersasync(...); } }
Comments
Post a Comment