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

Popular posts from this blog

Why does Ruby on Rails generate add a blank line to the end of a file? -

keyboard - Smiles and long press feature in Android -

node.js - Bad Request - node js ajax post -