Calling Invoke
is expensive only in that it involves a thread context switch and (possibly) waiting for the UI thread to become available. But if your UI thread isn't tied up doing a bunch of other stuff, and you're not trying to do hundreds of picturebox updates a second, then it's unlikely to be a noticeable problem. If the image is of any significant size, drawing the pixels is going to take so much time that the microseconds it takes for the Invoke
will be insignificant.
More importantly, you must do the update on the UI thread. So either you do all of your processing on the UI thread, or you use Invoke
to marshal the update to the UI thread. Since you don't want to tie up the UI thread doing calculations, you don't really have a choice.
The difference between having img
as a function parameter or as a member of a class is insignificant.
BeginInvoke
can be useful, but you have to be careful. All BeginInvoke
does is queue a request so that your background thread can get on with its work and the UI thread can update its display when it has time. It's very easy to queue so many requests with BeginInvoke
that the UI thread is spending near all of its time handling those requests and the rest of the UI appears to lock up because user-initiated actions got stuffed in the queue after the update actions. If you're doing many dozens of image updates per second, depending of course on the image size, your UI thread will never catch up. Your UI will lock up and eventually you'll run out of memory to queue requests.
It appears that your major performance bottlenecks here are doing the calculations on the image and then displaying the image. Both of those operations are so time intensive that whatever time you spend in Invoke
is likely irrelevant.
If your program's performance using Invoke
is good enough, then you're probably better off leaving it as it is. You can try using BeginInvoke
but as you say that'll require cloning the image. In addition, you might experience a locked-up UI.
In short, the answer to your questions is, "it depends." I don't know enough about your image processing or the amount of time it takes to do that processing. If you're curious, try it with BeginInvoke
and see. Worst that can happen is that your program crashes and you have to go back to using Invoke
. But be sure to test thoroughly over an extended period.
Your last question is unclear. If you're asking if it's dangerous to do UI updates on a background thread, the answer is a resounding "Yes!" Updating the UI on any thread other than the UI thread can lead to all manner of strange and wonderful bugs that are nearly impossible to duplicate at times, and very difficult to track down. Windows expects UI elements to be updated on a single thread.