I'm new to C# and I'm doing a project needs two timer to access the same variable at the same time.(one to read and other one to write or update).So, my problem is which Timer should I use? Forms.Timer or Thread.Timer. I've read some article about their difference. Since I want to use these timers to update the Interface of the program (image in picture box), So I think Forms.Timer should be used here since it's related to GUI stuff. However, the order that which timer executes first is also matter, so I think Thread.Timer should also be considered. Is there any way I can combine them together?
Update: I'm doing a ECG project, so basically I'm keeping receiving data and I want to draw them on the form. however, since drawing took about 40 ms, so using one timer would have delay but I need real time.(For example, If I set the interval to 100 ms, then It took 140 ms to finish one frame drawing that should be finished in 100 ms. This will cause 40 ms delay for every tick. ) Therefore, My solution is using one timer to update the data buffer when I received the data, and use other timer to call Invalidate, which would repaint all the new data. Should I use thread.timer to do the updating of data and form.timer to redraw the form?
The main difference between both timers is that the Form.Timer works in the same thread as your Form, so there is no problem in accessing or changing state of any GUI component (control etc.) by Tick event handler code. In case of Thread.Timer, there is no guarantee that the TimerCallback method is called from current thread (can be, but not must be), so accessing the GUI components can be slightly hard and not easy (you have to use Invoke(), like here: Accessing a form's control from a separate thread). On the other hand, any long-term and intensive processing, implemented in Form.Timer.Tick handler will be executed in same thread as GUI, so it can degrade GUI efficiency and responsibility. So, the general rule is: for fast, short-term operations on GUI components, use Form.Timer, and for long-term, heavy computations, not requiring access to GUI components, use Thread.Timer. Of course, it is simplified rule - the final decision should depend to specific case.
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.
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 am new to the world of GUI programming and I am writing a little GUI app using IronPython and WinForms. It reads values from an external device and displays them in a ListView component (name, value). I want to periodically perform the reading and updating of the ListView component at a certain fixed rate.
I had the following ideas to accomplish this:
A timer, which periodically triggers the read/screen update directly in the OnTick handler
A timer, whose OnTick handler triggers a BackgroundWorker to perform the read/update
Since the first solution will block the GUI until the read/update loop is done, which, depending on the number of values being read from the device, could take some time, I think the BackgroundWorker might be a better solution. I might want to add some functionality to manipulate the ListView items later (add, remove values etc.) and a blocked GUI does not seem like a good idea.
Is there a certain design pattern or a better way to accomplish reading/updating screen data?
NOTE: Any code examples can be IronPython or C#. The conversion from C# to IronPython is pretty straight forward. Thanks!
Personally, I'd have one thread that's responsible for reading values out of the device and storing the data in a data structure, and then a System.Windows.Forms.Timer (there's 3 Timers in .NET, this is the only one that ticks in the thread that's safe to update your controls) to read values out of that data structure and update the UI. You may need to synchronise that data structure, you may not.
That way the device can take as long as it likes to return data, or it can push as many millions of rows per second at you, and the UI thread will still poll at your predetermined tick rate (probably every 100 msec?). Since your timer ticks are just reading data out of memory, the UI won't block for IO.
The BackgroundWorker is prefered when you have lot of work to do in the background.
Use a Timer to trigger a function that will do the necessary work in a second thread.
It won't block the UI. (don't forget to update the controls on the UI thread).
System.Threading.Thread newThread;
newThread = new System.Threading.Thread(anObject.AMethod);
http://msdn.microsoft.com/fr-fr/library/ms173178(VS.80).aspx
Another option rather than getting the Timer and the Background worker thread working would be to use the System.Threading.Timer, this will execute your method on a thread on a regular interval and once you have the data you can use Control.Invoke or Control.BeginInvoke to update the control in the UI thread.
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.
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.