I'm developing a win forms, continious 24/7 video player and I need some help deciding which Threading class suits my needs. This is my first multithreading attempt. I'm familiar with the BackgroundWorker class, couple of properties to set and events to handle, but I have not delved much deeper to the rest of the Threading classes. I'm considering my application's tasks simple but I might be wrong regarding the level of simplicity.
Here's some of the player's functionality:
Reads an SQL Server database and displays data on a DataGridView.
Adds DataRepeaterItems to a DataRepeater control (serving the purposes of a playlist) from DataGridView CellMouseDoubleClick event.
Loads the video sound on a secondary (preview) player with each CellMouseClick event.
The player's PLAY button loads and plays the video on a video player instance, updates some labels, adds a DataRepeaterItem on a secondary DataRepeater (serves the role of a playlist history) and deletes the current DataRepeaterItem, the one currently playing, from the playlist DataRepeater control.
There are a couple more buttons deleting all DataRepeaterItems and moving the Items up and down the list.
Later something like an auto-playlist functionality will be added, populating DataRepeater control with multiple items based on some criteria. (24/7 player)
Why do you guys think? Is it safe to go with BackgroundWorker or is it better to look at the other Threading classes?
Well if you are using .Net 4 or above I would recommend Task class rather than Background Worker
Task class is certainly improvement over BackgroundWorker. It has more flexibility. You can write more elegant code using Task than BackgroundWorker. For example you can avoid event handlers involved in BackgroundWorker by using concept of task continuation.
Definitely use Tasks if .NET 4 is available. They have so many useful features:
The ability to queue more work for the same Task when the current work has completed.
Marshaling of exceptions to the calling thread.
"Smart" scheduling.
and many more. Check this source for a good overview of what you can do.
Related
I make some tests with C# and Windows Forms.
At the moment I am trying to implement some animations, for example display the current time or display a loading animation.
I looked around the internet but some solutions I found looked a bit ugly.
For example the most people create a Timer and refresh the animation at a specific frequency.
But I don't think thats the purpose of a timer...
So I found a second solution.
Simply register for the Application Idle event so I can update some animations and other processing stuff as part of the main application loop.
This sounds like a better solution.
Also I am wondering how I should request a redraw of some custom animated controls.
Simply call Invalidate() or Update() whats the recommend way?
Whats the professional way of update and redraw such things like a timer or other animations of custom controls?
There is a background worker, you can read more about it here: https://msdn.microsoft.com/en-us/library/cc221403%28v=vs.95%29.aspx?f=255&MSPPError=-2147217396
Or you can use async/await - a Task based asynchronous approach
https://msdn.microsoft.com/en-us/library/hh191443.aspx
There is a form. On the form there is a pictureBox docked on all form's surface.
When app starts, for a second a form with white surface is displayed, then
the picture is shown.
how can i get rid of that 1s white form?
Sounds like you are doing something time consuming in form_Shown event. Call Form's Refresh() method as the first thing in form shown -event and it will first draw the form, then do the time consuming things
You have not stated when you are loading the picturebox with your image. But I would try making your picturebox visible at the end of your Form_Load event or in your Form_Shown event.
Sounds more like a threading problem to me. I guess that your UI thread is doing too much work and cannot update the UI often enough.
Do all of the following:
Make sure loading and processing any data (including the images) is NOT located in the constructors.
Move that code into the appropriate FormLoad() event handler methods.
Implement loading of the images so that it runs a separate thread.
You can find some advice in this MSDN article: Give Your .NET-based Application a Fast and Responsive UI with Multiple Threads
If you are working in a .NET 4.x version, you can also use the Task Parallel Library to make working with multiple threads easier.
The upcoming .NET 4.5 also offers the even more comfortable await and asyc keywords: Asynchronous Programming with Async and Await.
I am looking for advice and help regarding a specific use case of an application.
Here's the use case:
A user our our WPF application goes crazy and starts clicking all over, triggering a number of events before the first (or previous) event(s) have to finish.
Currently, WPF queues any and all clicks and queues them for sequential execution. Ideally we would like to queue up to 3 events and drop and disregard any and all clicks (user interactions) after the first 3.
What would be the best approach to solving this issue, what is the best practice for this use case. Any documentation, code and/or help would be much appreciated.
Since this really is a windows issue and not specifically a WPF issue, the only thing I can think of is hooking the message queue and discarding clicks within a certain time unless you write specific handlers into each control. The other option is to write the application such that feedback is provided to the user during an operation and input is disabled.
What does WPF use to capture mouse and keyboard input?
If you'd use MVVM all UI actions are bound to ViewModel commands or properties. In the ViewModel you'd have full control over how many and how frequently you want to process what comes from the UI. It will probably involve some sort of producer consumer queue.
Also if your user actions block the UI, you need to process them outside the UI thread as much as possible.
My program consists of a large graphing UI control that I need to spend about 15 seconds re-loading every once in a while. Because the updating code works primarily with the UI control (maybe 90% of it actually sets properties on the control), it would make sense to me to actually let the UI thread handle that. I really don't want the control to visually re-paint while it is loading in a separate thread from the UI.
I also want a progress bar to update as well that lives in the status bar of the same application window. Is there a way to break the rule in this case and re-paint only the progress bar, or should I just open a new application window for the progress bar to live in?
What would you do in this particular case?
If you can break your primary task (ie. updating the graph) in many steps, you can perform each step as a separate dispatcher message. This will allow other messages to be processed, including giving you the ability to update progress information.
The basic pattern is:
Invoke your primary task, passing in zero for the step.
Perform the step.
If there are more steps, queue another message, passing in step + 1.
You can then add in progress updates at the appropriate points in your code.
PS. Not saying this is your best option - hard to tell without knowing all the details. But this is an option.
It is not really true that there is only one UI thread in an application, it is just that most windows applications only ever create UI objects in one thread so this thread becomes "the" UI thread in the application. It is easy to understand why - this makes the code simpler to understand, and protects us from implicit thread binding issues between controls.
This suggests a possible idea, should it prove impossible to improve the speed of updating the control (which is what I would suggest to do first). Create the UI control on a separate thread. You need to make sure that the thread is suitable for UI, that is to say the threading model is STA, and that it will pump messages and not die before the control is destroyed. I don't know if you need to create the parent window in the UI thread as well, or just the control but it may be worth experimenting here.
Find a graphing UI control that is more efficient. Unless the UI thread yields to the message loop any other updates won't happen (and it will slow down your graph control's updates).
I would suggest using a progressbar in a new window (without the form headers). Make it paint the progress bar by reading the shared properties of a graph control. this way you can avoid the thread blocking (sluggish loading).. And it gives you good visual experience (progressive painting on both the controls).
I'm looking at creating a tabbed interface which has user controls (possibly written by plug-in developers) within a tabbed or MDI interface. These plug-in controls could unintentionally freeze their GUI thread, and I'd prefer that they not influence user controls in other tabs. Much like Google Chrome creates a process for each tab; but in this case, just threads.
Or perhaps even an MDI interface where the child MDI forms are owned by separate threads?
I've found that while I can run multiple GUI threads at once, the Form level is where they MUST be separated. Any workarounds/ideas?
For those saying this shouldn't be needed, I call bullshit. Google's Chrome browser runs tabs in separate processes for security and UI reasons. I'm merely trying to duplicate this behavior. When the people writing the user controls are sucky plug-in developers, this is important.
No it is not possible to do this in the way you are describing. A control which is owned / affinitized to another GUI thread cannot be directly contained within a control which is owned / affinitized to a different thread in such a way that it's paint function runs on the other thread.
The right way to fix this situation is to write UserControls that don't perform long-running tasks on the UI thread. If the control is blocking and waiting on some computational task, fix that. Make that task run in the background, and have the control display some non-compute-intensive content until it's done. If that task freezes, the control will be frozen in its "I'm waiting..." state, but it won't intrude on the rest of the UI.
If you're using a third-party control that you can't fix, well, in the immortal words of Jay-Z, I feel bad for you, son.
For the most part, controls shouldn't be performing any processing. Their purpose is to provide interactivity between the user and the application. For example, it is not the job of a button to fetch data from a database and present it to the user. That being said, hopefully you are doing your processing in a controls event handler, such as the Click event on the Button control. In your event handler, you can prevent the UI from appearing "hung" by processing tasks in a background thread. The BackgroundWorker is often useful in these situations.
I suggest reading up on Threading. The Microsoft® .NET Framework Application Development Foundation book has a section on threading (even if no other certification books are read, I at least recommend all .NET developers read this book). Just remember not to update the UI from a child thread. Read an example on how to make a thread-safe call to Windows controls if you're not familiar with this approach.
Instead of having or owning different GUI threads, you should view the whole issue from a different angle. Why would you want a thread associated to tab's child control to be freezed? If it does freeze and everything else feezes too, threading aside, that's not done right from ground up.
What JaredPar pointed out is correct, but that doesn't mean you cannot achieve what you want. I assume you want stuff running within a tab to continue running/stopping without affecting other controls and user-experience.
I've done it before in a complex WinForm app. Here are some readings which might give you more insights:
Threading out tasks in a C#.NET GUI
Thread and GUI
Updating GUI from Other Threads in C#
Advanced Techniques To Avoid And Detect Deadlocks In .NET Apps