c# - Cross-thread exception when trying to update image from byte array -


i working on application shows 2 videos side-by-side (unfortunately custom format).

when try display video frames, "cannot access object because different thread owns it"-exception, though thought calling dispatcher fix that.

it seems people have had similar problems when using bitmapimages or similar, , solve problem via freezing image, in case, receive byte array, not seem have freeze-method.

this problematic code (which called async method):

private void showvideo(string filename) {     colorvideo video = new colorvideo(filename); // colorvideo reads frames disk      writeablebitmap image = new writeablebitmap(video.width, video.height, 96, 96, pixelformats.bgr32, null);      // set image source image frame in ui     this.dispatcher.begininvoke((action)delegate     {     this.imageframe.source = image;     });      (int i=0; < video.length, i++)     {         byte[] framebytes = video.getframe(i);          // following line throws exception.         // wrapping line inside call dispatcher doesn't         // cross-thread exception regardless          image.writepixels(new int32rect(0,0,video.width,video.height),framebytes, video.width*4,0);     } } 

now, suspect approach may not ideal, anyway. want able run showvideo method in background , have update image shown 30 times second. how can better?

note first creating bitmap, issuing begininvoke+setsource operations dispatcher, , write pixels.

this leaves race: dispatcher can first set bitmap source, , loop may run , try modify pixels. since loop runs in background thread, writepixels may throw. have not checked, guess.

so, first try:

your-for-loop {    create-a-bitmap    get-frame    write-pixels     // xxx     this.dispatcher.begininvoke((action)delegate    {        this.imageframe.source = image;    }); } 

so moving start of dispatcher block may remove problem, ensure loop not write bitmap pushed ui.

in setup, can still add "freeze" @ xxx marks, allow wpf skip intermediate copies of bitmaps, not single copy done during rendering. however, adding freeze not @ fact loop allocate , throw out new bitmaps.

the fact of creating them create pressure on memory , gc. not bitmaps created, must periodically found , removed gc. can circumvent little creating two bitmaps , reusing them flipping odd-even:

create-bitmap-1 create-bitmap-2 your-for-loop {    get-frame     if frame-number odd       write-pixels bitmap-1    else       write-pixels bitmap-2     this.dispatcher.begininvoke((action)delegate    {        if frame-number odd            this.imageframe.source = image1;        else            this.imageframe.source = image2;    }); } 

note important thing: when using way, cannot freeze bitmaps wpf in caching , cut number of intermediate copies. not want make them cacheable, , need bitmaps modifiable. slow down renderer and/or compositor thread, lower pressure on gc , cpu in overall.


Comments

Popular posts from this blog

php - SPIP: From Tag directly to an article -

jquery - isAjaxRequest always return false -

ruby on rails - In a controller spec, how to find a specific tag in the generated view? -