c# - Async/await deadlock while downloading images -
i'm developing windows phone 8.1 app. have screen list of news' titles thumbnails.
first i'm making asynchronous http request news collection in json (satisfying notifytaskcompletion
pattern)
newscategories = new notifytaskcompletion<observablecollection<newscategory>>(_newsservice.getnewscategoriesasync());
newscategory:
public class newscategory : observableobject { ... public string title { get; set; } public observablecollection<news> items { get; set; } }
news:
public class news : observableobject { ... public string title { get; set; } public string imagepath { get; set; } }
so far works perfectly, imagepath
property, download , display given image. i've found solution asynchronously here: wp 8.1 binding image http request - when xaml gets image path, calls converter class (binarytoimagesourceconverter
), using notifytaskcompletion
pattern.
the problem occurs in following method:
private async task<bitmapimage> getimage(string path) { httpclient webclient = new httpclient(); var responsestream = await webclient.getstreamasync(path); var memorystream = new memorystream(); await responsestream.copytoasync(memorystream); memorystream.position = 0; var bitmap = new bitmapimage(); await bitmap.setsourceasync(memorystream.asrandomaccessstream()); return bitmap; }
when first await
called, debugger never reach next line , method never returns. string path
variable has proper content.
so far have tried use configureawait(false)
, doesn't work in case.
i have found out in topic: deadlock while using async await , that:
when you're using
configureawait(false)
, tell program dont mind context. can solve deadlocking problems, isn't right solution. right solution never wait tasks in blocking way, , being asynchronous way.
i don't know have stuff in blocking way. can reason deadlock?
and if it's wrong approach, know pattern more appropriate downloading thumbnails collection of items?
thank help.
update: how getimage
invoked: it's in topic: wp 8.1 binding image http request
public class webpathtoimage : ivalueconverter { public object convert(object value, type targettype, object parameter, string language) { if (value == null) return null; return new notifytaskcompletion<bitmapimage>(getimage((string)value)); } public object convertback(object value, type targettype, object parameter, string language) { throw new notimplementedexception(); } private async task<bitmapimage> getimage(string path) { using (var webclient = new httpclient()) { webclient.defaultrequestheaders.add("user-agent", "bot"); var responsestream = await webclient.getstreamasync(path).configureawait(false); var memorystream = new memorystream(); await responsestream.copytoasync(memorystream); memorystream.position = 0; var bitmap = new bitmapimage(); await bitmap.setsourceasync(memorystream.asrandomaccessstream()); return bitmap; } } }
and in xaml:
<image datacontext="{binding imagepath, converter={staticresource webpathtoimage}}" source="{binding result}" stretch="uniformtofill" height="79" width="79"/>
first, if on windows phone 8.1 recommended use httpclient
namespace windows.web.http
, not system.net.http
. reasons explained on this link.
my answer uses new windows.web.http.httpclient
getimage
method can this:
private async task<bitmapimage> getimage(string path) { using (var webclient = new windows.web.http.httpclient()) { webclient.defaultrequestheaders.add("user-agent", "bot"); var responsestream = await webclient.getbufferasync(new uri(path)); var memorystream = new memorystream(responsestream.toarray()); memorystream.position = 0; var bitmap = new bitmapimage(); await bitmap.setsourceasync(memorystream.asrandomaccessstream()); return bitmap; } }
i have tested method on sample url , displayed correctly in image
control.
second, why don't let image
control handle downloading bitmapimage
without converter, xaml looks this:
<image source="{binding imagepath}" stretch="uniformtofill" height="79" width="79" />
this way imagepath
can path resource internet , local resource.
Comments
Post a Comment