I want to paralelize a 3D voxel editor built on top of Windows Forms, it uses a raycaster to render so dividing the screen and getting each thread on a pool to render a part of it should be trivial.
The problem arises in that Windows Forms' thread must run as STA - I can get other threads to start and do the work but blocking the main thread while waiting for them to finish causes strange random deadlocks as expected.
Keeping the main thread unblocked would also be a problem - if, for example, the user uses a floodfill tool the input would be processed during the rendering process which would cause "in-between" images (an object partially colored, for example). Copying the entire image before every frame isn't doable either because the volumes are big enough to offset any performance gain if it has to be copied every frame.
I want to know if there is any workaround to get the amin thread to appear blocked to the user in a way that it will not be actually blocked but will delay the processing of input till the next frame.
If it isn't possible, is there a better design for dealing with this?
EDIT: Reading the anwsers I think I wasn't clear that the raycaster runs in real time, so showing progress dialogs won't work at all. Unfortunately the FPS is low enough (5-40 depending on various factors) for the input between frames to produce unwanted results.
I have already tried to implement it blocking the UI thread and using some threads of a ThreadPool to process and it works fine except for this problem with STA.
This is a common problem. With windows forms you can have only one UI thread. Don't run your algorithm on the UI thread because then the UI will appear frozen.
I recommend running your algorithm and waiting for it to finish before updating the UI. A class called BackgroundWorker comes pre-built to do just this very thing.
Edit:
Another fact about the UI thread is that it handles all of the mouse and keyboard events, along with system messages that are sent to the window. (Winforms is really just Win32 surrounded by a nice API.) You cannot have a stable application if the UI thread is saturated.
On the other hand, if you start several other threads and try to draw directly on the screen with them, you may have two problems:
You're not supposed to draw on the UI with any thread but the UI thread. Windows controls are not thread safe.
If you have a lot of threads, context switching between them may kill your performance.
Note that you (and I) shouldn't claim a performance problem until it has been measured. You could try drawing a frame in memory and swapping it in at an appropriate time. Its called double-buffering and is very common in Win32 drawing code to avoid screen flicker.
I honestly don't know if this is feasible with your target frame rate, or if you should consider a more graphics-centered library like OpenGL.
Am I missing something or can you just set your render control (and any other controls that generate input events) to disabled while you're rendering a frame? That will prevent unwanted inputs.
If you still want to accept events while you're rendering but don't want to apply them until the next frame, you should leave your controls enabled and post the detail of the event to an input queue. That queue should then be processed at the start of every frame.
This has the affect that the user can still click buttons and interact with the UI (the GUI thread does not block) and those events are not visible to the renderer until the start of the next frame. At 5 FPS, the user should see their events are processed within 400ms worst case (2 frames), which isn't quite fast enough, but better than threading deadlocks.
Perhaps something like this:
Public InputQueue<InputEvent> = new Queue<InputEvent>();
// An input event handler.
private void btnDoSomething_Click(object sender, EventArgs e)
{
lock(InputQueue)
{
InputQueue.Enqueue(new DoSomethingInputEvent());
}
}
// Your render method (executing in a background thread).
private void RenderNextFrame()
{
Queue<InputEvent> inputEvents = new Queue<InputEvent>();
lock(InputQueue)
{
inputEvents.Enqueue(InputQueue.Dequeue());
}
// Process your input events from the local inputEvents queue.
....
// Now do your render based on those events.
....
}
Oh, and do your rendering on a background thread. Your UI thread is precious, it should only do the most trivial work. Matt Brundell's suggestion of BackgroundWorker has lots of merit. If it doesn't do what you want, the ThreadPool is also useful (and simpler). More powerful (and complex) alternatives are the CCR or the Task Parallel Library.
Show a modal "Please Wait" dialog using ShowDialog, then close it once your rendering is finished.
This will prevent the user from interacting with the form while still allowing you to Invoke to the UI thread (which is presumably your problem).
If you don't want all the features offered by the BackgroundWorker you can simply use the ThreadPool.QueueUserWorkItem to add something to the thread pool and use a background thread. It would be easy to show some kind of progress while the background thread was performing it's operations as you can provide a delegate callback to notify you whenever a particular background thread is done. Take a look at ThreadPool.QueueUserWorkItem Method (WaitCallback, Object) to see what I'm referring you to. If you need something more complex you could always use the APM async method to perform your operations as well.
Either way I hope this helps.
EDIT:
Notify user somehow that changes are being made to the UI.
On a(many) background threads using the ThreadPool perform the ops you need to perform to the UI.
For each operation keep a reference to the state for the operation so that you know when it completed in the WaitCallback. Maybe put them in some type of hash / collection to keep ref to them.
Whenever an operation completes remove it from the collection that contains a ref to the ops that were performed.
Once all operations have completed (hash / collection) has no more references in it render the UI with the changes applied. Or possibly incrementally update the UI
I'm thinking that if you are making so many updates to the UI while you are performing your operations that is what is causing your problems. That's also why I recommended the use of SuspendLayout, PerformLayout as you may have been performing so many updates to the UI the main thread was getting overwhelmed.
I am no expert on threading though, just trying to think it through myself. Hope this helps.
Copying the entire image before every frame isn't doable either because the volumes are big enough to offset any performance gain if it has to be copied every frame.
Then don't copy the off-screen buffer on every frame.
Related
I should report several certain things to my GUI while another thread is running in the background, such as:
Progress Value
Elapsed Time
Number of Results Found in real-time
Number of Errors Occurred during the process
and so on
I can use this piece of code when I need to invoke the UI and change something:
private void DoInvoke(Action action)
{
try
{
if (InvokeRequired)
BeginInvoke(action);
else
action();
}
catch { }
}
It works well, GUI and background thread work very well and the info will be reported and shown in UI.
But there is a problem, because of so many contexts changing between the background thread and UI, the CPU usage will be very high! I need to update the UI values without this context changing and without CPU usage.
So I decided to make a class of needed values and send it to the background thread. so It is a reference in which both UI and background thread can access it.
and I have put an event handler inside the class, so whenever a value is changed it will invoke. in UI I have attached an event to this handler, so every time a value is changed in this class, the UI should update that value. But again I will face cross-thread error. How to handle such a thing? I do not want the high cpu usage and also I need real-time UI update.
There are various ways to approach this.
The first thing is to define "realtime". If your data changes every 1 millisecond, even if you were able to update the UI that fast, noone would be able to see it. As a guideline, we can only detect changes at around 60Hz (that's why videogames target that framerate). In practice, you probably want the UI to update in the 10-50Hz range.
The timer solution
A simple solution, which may or may not be appropriate, would be to setup a timer on the UI thread that fires at the appropriate rate and update your controls in the timer event handler.
The Invoke() / BeginInvoke() solution
Another option is to still use the BeginInvoke() approach, but:
Implement the logic to update all controls in a single function and only BeginInvoke() that one, so you only queue a single work item in the UI thread. If you were to do a BeginInvoke() for each control, you'd cause a context switch for each control.
Skip invoking a BeginInvoke() if a minimum time has not elapsed since the last update. For instance, if data has changed after 3 milliseconds, you could skip all updates until one happens after 50 milliseconds (that would give a max update rate of 20 Hz).
The complications
This will work fine if you have simple controls, however you could run into issues if you have complex ones, like graphs, of many many controls to update. In this case, it may take a long time to redraw them, so you could not be able to update the UI at the desired rate. In you BeginInvoke() too often and the UI thread can't keep up, the app will essentially freeze because it doesn't have time to handle the user input.
There could be other conditions that lead the main thread to be more busy than usual (resizing the window or other processing that takes max a couple of seconds and you didn't bother to run in a separate thread).
So, in my programs, I usually set a flag immediately before I call BeginInvoke(), and I clear it in the invoked function. The next time I have to call BeginInvoke(), I first check the flag. If it's still set, it means the UI thread was busy and still hasn't managed to update the UI. In that case, I skip the BeginInvoke().
Finally, if you have a lot of stuff going on (I had to update many graphs and views) you may also need to have your logic guarantee a minimum time from when the update code in the UI thread ends executing and when you queue a new update from your background thread. This guarantees there's some time left in the UI thread to process user input, while the thread is very busy updating the UI in the rest of the time.
Final notes
If a value has not changed, you want to avoid redrawing the relative control, because it's pointless. I expect most WinForms controls, like a label, to already not redraw if you set their Text to the same value they already have, but if you have custom controls, third party controls, or do things like clear a ListView and repopulate it, you want to make sure the code isn't causing a redraw when it's not needed.
A c# application I’m developing consists essentially of performing operations on images coming from a camera and printing them on a picturebox.
It has a library written in c++ that retrieves images from a webcam (imgcam), and makes copies of them (imgcam_copy), then they are delivered to the managed code who is requesting them.
In turn the managed part of the application consists of a secondary thread who executes a while cycle that takes images from the unmanaged library and prints them to a picturebox.
Everything works fine and the most delicate part of everything, that is the management of dynamic resources from unmanaged to managed code seems clear to me and I’m aware of what I’m doing (at least I hope), but the problem is with the writing of the code necessary for making threads work properly.
Indeed there are many things that are not clear to me, even after browsing the web for hours.
I’m compelled to print the image with UI thread, so I have to rely on Invoke.
delegate void setImageCallback(Image img);
private void showFrame(Image img)
{
if (pboxCam.InvokeRequired)
{
this.Invoke(new setImageCallback(showFrame), img);
}
else
{
pboxCam.Image = img;
}
}
I have many questions:
1) Is Invoke a costly operation? I’ve made many efforts to reduce the execution time of main operations on images, it would be disappointing to waste part of the gain in just showing the result.
2) Do you think that it is better to use synchronously Invoke or asynchronously BeginInvoke+copy of image?
3) Could it be helpful not having Image as function parameters but accessing it as member of a class ?
private delegate void setImageCallback();
private void showFrame()
{
if (pboxCam.InvokeRequired)
{
this.Invoke(new setImageCallback(showFrame));
}
else
{
pboxCam.Image = cm.bitmap;
}
}
4) maybe you won’t share my worry for the performance, but I would like to know if you share the one for thread safety. The UI thread just wants to display an image while the non-UI thread makes a copy of it, is it really unsafe to rely on an asynchronous mechanism?
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.
I have a C# Windows Forms application wicht does some camera control and computer vision. For all the parts which take longer for calculation I used seperate threads. But there are still some parts which are in the callback functions of the GUI. As I understand, all these callback functions are executed in the same thread. Is there a way to see how much time this thread is working or idle? What percentage of idle time is needed such that the GUI is still responsive?
It's recommended that you shouldn't block the UI thread for more than 50ms, otherwise it will affect the UI responsiveness. I.e., two UI callbacks queued with Form.BeginInvoke, each taking ~50ms to complete, may introduce some unpleasant UI experience to the user.
It doesn't make sense to update the UI more often than the user can react to it (i.e, ~24 frames per second). So, you should throttle the UI thread callbacks and give user input events a priority.
I recently posted an example of how it can possibly be done:
https://stackoverflow.com/a/21654436/1768303
For simple tasks you could use a stopwatch and measure the time manually. However I think you'll need to check what a performance profiler is.
Also - there is little situations in which your GUI needs that heavy processing. In most cases the problem comes from putting too much calculations in event handlers instead of implementing them somewhere outside and then update the form when finished. It's less of a single/multi-threading problem and more of using available events properly.
I'm doing all this in C#, in Visual Studio 2008.
I want to slow down the work of my algorithm so that the user can watch it's work. There is a periodic change visible at the GUI so I added Thread.Sleep after every instance.
Problem is that Thread.Sleep, when set to at least a second, after a few instances of Thread.Sleep (after few loops) simply freezes entire GUI and keeps it that way till program completion. Not right away, but it always happens. How soon depends on the length of the sleep.
I have proof that entire program does not freeze, it's working it's thing, even the sleep is making pauses of correct length. But the GUI freezes at certain point until the algorithm ends, at which point it shows the correct final state.
How to solve this issue? Alternative to pausing algorithm at certain point?
First off, don't make the user wait for work that is done before they even think about when it will be finished. Its pointless. Please, just say no.
Second, you're "sleeping" the UI thread. That's why the UI thread is "locking up." The UI thread cannot be blocked; if it is, the UI thread cannot update controls on your forms and respond to system messages. Responding to system messages is an important task of the UI thread; failing to do so makes your application appear locked up to the System. Not a good thing.
If you want to accomplish this (please don't) just create a Timer when you start doing work that, when it Ticks, indicates its time to stop pretending to do work.
Again, please don't do this.
I'd guess everything is running out of a single thread. The user probably invokes this algorithm by clicking on a button, or some such. This is handled by your main thread's message queue. Until this event handler returns, your app's GUI cannot update. It needs the message queue to be pumped on regular basis in order to stay responsive.
Sleeping is almost never a good idea, and definitely not a good idea in the GUI thread. I'm not going to recommend that you continue to use sleep and make your GUI responsive by calling Application.DoEvents.
Instead, you should run this algorithm in a background thread and when it completes it should signal so to the main thread.
You are about to commit some fairly common user interface bloopers:
Don't spam the user with minutiae, she's only interested in the result
Don't force the user to work as fast as you demand
Don't forbid the user to interact with your program when you are busy.
Instead:
Display results in a gadget like a ListBox to allow the user to review results at her pace
Keep a user interface interactive by using threads
Slow down time for your own benefit with a debugger
This depends on a lot of things, so its hard to give a concrete answer from what you've said. Still, here are some matters that might be relevant:
Are you doing this on a UI thread (e.g. the thread the form-button or UI event that triggered the work started on)? If so, it may be better to create a new thread to perform the work.
Why do you sleep at all? If the state related to the ongoing work is available to all relevant threads, can the observer not just observe this without the working thread sleeping? Perhaps the working thread could write an indicator of the current progress to a volatile or locked variable (it must be locked if it's larger than pointer size - e.g. int or an object - but not otherwise. If not locked, then being volatile will prevent cache inconsistency between CPUs, though this may not be a big deal). In this case you could have a forms timer (there are different timers in .Net with different purposes) check the status of that variable and update the UI to reflect the work being done, without the working thread needing to do anything. At most it may be beneficial to Yield() in the working thread on occasion, but its not likely that even this will be needed.
I am using c# to integrate with a web cam. I need to generate a snapshot image every x milliseconds and save it to file.
I already have the code up and running to save to file on a button click event, however I wonder what am I supposed to do when taking snapshots in the background - Should this be multi threaded? I'm honestly not sure.
I could just block the UI thread, put Thread.Sleep and then just take the snapshot, but I don't know if this is right.
I thought of using a background worker, but I am now experiencing cross threaded difficulties with SendMessage... So I wonder if I should even go and bother to multi-thread or just block the UI.
There will be a physical hardware limit to how fast the camera can update its pixel buffer. Webcams don't go far above 30fps. Getting the actual image should be more or less instantaneous (unless at very high res), so you would not require threading to start off with. When I did it a while ago I used the approach as given on
http://weblogs.asp.net/nleghari/pages/webcam.aspx
I think you should put this task on a separate thread. The process of creating and saving the image may take more time is some situations and at that time your HMI may freeze. To avoid this put this task on a separate thread.
You could create a timer to kick a delegate every n milliseconds and that delegate could queue a worker thread to do what your OnClick() handler does already.
I would NOT write this as a single-threaded app because, depending on the performance of the user's webcam, you could easily end up in an eternal loop handling timer events, causing your main UI thread to be permanently blocked.
ThreadQueue.QueueUserWorkitem((args) =>
{
// Blah ...
}
should not require much effort to get working correctly.