c# wpf Updating UI source from BlockingCollection with Dispatcher -
here's problem.
i'm loading few bitmapimages in blockingcollection
public void blockingproducer(bitmapimage imgbsource) { if (!collection.isaddingcompleted) collection.add(imgbsource); }
the loading happens in backgroungwork thread.
private void worker_dowork(object sender, doworkeventargs e) { string filepath; int imgcount = 0; (int = 1; < 10; i++) { imgcount++; filepath = "snap"; filepath += imgcount; filepath += ".bmp"; this.dispatcher.begininvoke(new action(() => { label1.content = "snap" + imgcount + " loaded."; }), dispatcherpriority.normal); bitmapimage imgsource = new bitmapimage(); imgsource.begininit(); imgsource.urisource = new uri(filepath, urikind.relative); imgsource.cacheoption = bitmapcacheoption.onload; imgsource.endinit(); blockingproducer(imgsource); } }
debugging part of code looks okay, problem comes ...
after finishing loading images want show them in ui 1 one. i'm using dispatcher message telling me called thread can not access object because belongs different thread.
public void display(blockingcollection<bitmapimage> results) { foreach (bitmapimage item in collection.getconsumingenumerable()) { this.dispatcher.begininvoke(new action(() => { this.dstsource.source = item; thread.sleep(250); }), dispatcherpriority.background); } }
debug accuses error here
this.dstsource.source = item;
i'm trying cant find out what’s wrong. has idea?
you have call freeze
after loading images in order make them accessible other threads:
bitmapimage imgsource = new bitmapimage(); imgsource.begininit(); imgsource.urisource = new uri(filepath, urikind.relative); imgsource.cacheoption = bitmapcacheoption.onload; imgsource.endinit(); imgsource.freeze(); // here
as far have understood bitmapcacheoption.onload
flag, effective when bitmapimage loaded stream. remarks section in bitmapcacheoption says:
set cacheoption bitmapcacheoption.onload if wish close stream used create bitmapimage. default ondemand cache option retains access stream until image needed, , cleanup handled garbage collector.
a bitmapimage created uri may loaded asynchronously (see isdownloading
property). consequently, freeze
may not callable on such bitmapimage, downloading may still in progress after endinit. guess nevertheless works in case because loading bitmapimages file uris, seems done immediately.
to avoid potential problem may create bitmapimage filestream:
var imgsource = new bitmapimage(); using (var stream = new filestream(filepath, filemode.open)) { imgsource.begininit(); imgsource.streamsource = stream; imgsource.cacheoption = bitmapcacheoption.onload; imgsource.endinit(); imgsource.freeze(); }
Comments
Post a Comment