c# - What is the correct way to access a remote resource in my MVC controller? -
i using mvc 5 on .net , have user flow looks this:
- user enters address form.
- form gets posted controller using ajax.
- controller records address database.
- controller makes webclient request bing maps geocode address latitude , longitude.
- controller records latitude , longitude database.
- controller returns ajax result rendered client-side updated view address , latitude/longitude.
i know call bing maps should happen in async context site's speed uncoupled of bing maps.
instead think flow should work this:
- user enters address form.
- form gets posted controller using ajax.
- controller records address database.
- controller launches async task geocoding , update database
- controller returns ajax result client shows updated address , tells poll client-side completion of geocode result.
i stuck on step #4. here have:
public actionresult getlocation(int id) { listing li = db.listings.find(id); task.run(() => { // update geocode if necessary if (li.bizaddress.geostatus != businessaddress.geocodestatus.uptodate && datetime.now - li.bizaddress.lastgeoattempt > timespan.fromhours(1)) { geocoder geo = new geocoder(); geocoderesult gr = geo.geocode(li.bizaddress).result; if (gr.badresult != true) { li.bizaddress.latitude = gr.location.latitude; li.bizaddress.longitude = gr.location.longitude; li.bizaddress.geostatus = businessaddress.geocodestatus.uptodate; } else { // failed li.bizaddress.latitude = 0; li.bizaddress.longitude = 0; li.bizaddress.geostatus = businessaddress.geocodestatus.badresult; } li.bizaddress.lastgeoattempt = datetime.now; db.savechanges(); } }); return partialview("~/views/listing/listingpartials/_location.cshtml", li); }
however exception db context has been disposed of when db.savechanges().
i want task run async inside of closure db still valid undisposed variable.
is possible? i'm new async programming , don't know of idioms yet.
additional info: rendering panel in view this:
@{html.action("getlocation", new { id = model.id });}
i want keep behavior since loading ajax may hurt seo.
firing off task in way not practice. instead, mark actionresult signature async
, await
results need inside method body. way won't tying server resources waiting response bing. frees having worry instructing client side poll future result consider anti-pattern in async programming. it's easier deal in 1 call , send result when it's available. since you're using ef6 can leverage async methods improve server performance.
public async task<actionresult> getlocation(int id) { var listing = await db.listings.findasync(id); ... var gr = await geo.geocode(li.bizaddress);
at least, if you're sure want go down path important clean task code. it's bad practice use .result tasks inside of web server locks server threads. change definition of task async:
task.run(async () => { // update geocode if necessary if (li.bizaddress.geostatus != businessaddress.geocodestatus.uptodate && datetime.now - li.bizaddress.lastgeoattempt > timespan.fromhours(1)) { geocoder geo = new geocoder(); geocoderesult gr = await geo.geocode(li.bizaddress);
Comments
Post a Comment