I can't seem to figure out how to use either the threading or Backgroundworker task. My problem is that I am loading a large XML file into a TreeView and would like to display a progress bar while doing so. The issue right now is that the app freezes when it's loading and says the app is non-responsive.
Threading / Background worker tasks is new to me so I am not exactly sure how to make this work.
First we will start with my button to get the user details
So we get the users's details and call CreateXML for the user detail object. So we have the XML in one big string called strXML. Then I call dom.LoadXml to load xml sting into the dom object. Then we initialize the tree view control and add the nodes etc.
So during this whole process the app hangs and indicates that it's not responding while it's busy churning thought the XML and creating it into a treeview. I want to put in a progress bar so the end user see's that something is actually going on and they don't think the app just died on them.
How would i implement some sort of progress bar with a thread or back ground worker?
Please just don't redirect me to link after link because that never really works for me.
Thanks
I was able to implement multi-threading which then I was able to achieve the progress bar moving while the data was being loaded. Sometimes people need to wait for data to be loaded and a simple indicator is all that's needed so users know the app is working.
Related
I am not sure how should I put the title of my question, But I have one issue in Window based application C# code.
basically I am creating 2 WPF application in C#
For my First application, following steps are there
A. I am Creating some folders by C# code and showing status on a TextBox.
B. Then I am unzipping a folder by C# code and Copying files to a new folder location in C drive. This time also I have to show the status in TextBox.
But there is a problem with second step. Copying files blocked the first step to show the status in TextBox. I was hoping that It should show the status in TextBox first for the first step then it should start the coping files. Right now it shows the complete message in TextBox, after coping the files. :(
For my second application, I load XML with more then 3000 data in a List. So Loading and displaying the items in the list, block the entire application. So how could I resolve this?
I am new in .net, so please help me in that.
You need to use Threads or Background Workers to accomplish this task. When you do some work in single application, your UI will get block till some Long Task get completed [in your case updating your text box].
Also to access UI components not inside your own thread [Original thread] you will need Invokes. Go through guides and try to adapt techniques in them. In my experience "Background workers" are easy to work with.
Guides -
Backgorund workers
Invokes
Updating UI- in your case show progress
When a browser is opened, before it's completely loaded, we can use the controls as others are being loaded (the address bar appears and, while the bookmarks are loaded, we can already type in it).
I'm making a personal browser, and I don't know how to perform that. I imagined creating the controls in another thread, but soon I discovered that that's not possible.
In my last question (where I discovered the above), I received an answer talking about Attribute, Reflection, async/await modifiers and observable collection as the closest solution to that and I'll study them yet. In this new question, I would like to receive others suggestions of how that could be made (allow the user to use the window and controls while others are being created/loaded).
Thanks in advance.
Actually I believe the process of loading the UI part of controls isn't the heavy one.
In the other hand, loading the data which is later bound to the control is the problem.
You can't draw controls outside UI thread, but you can load heavy data, preload resources or do calculation in a background thread.
While heavy controls' data is prepared to hit the UI in some background thread, UI will still be responsive.
For example, I guess Web browsers do HTML to DOM parsing in a background thread and they stream results in real time to the UI thread. That is, address bar and other UI components are responsive because UI thread isn't stressed.
I have a method called GetAllRecords() that will return a datatable of 200K records. When I checked it took about 5 seconds to load data to the datagrid and window froze.
DataTable dt = Records.GetAllRecords();
I know I have to use Background worker controls and it's three events, but I cannot figureout how to use them properly. For instance, the progress bar must show real progress not a fake one. I could slow the progress bar using sleep() of the thread class but it would be a fake progress bar.
Could any one here please give me step by step instructions on how to create a real progress bar on my windows form?
Before .NET 2.0 there was not Background worker control, in those days how programmer wrote real progress bars?
thanks
If you do a search of the site, as well as Google, you'll see that there are several attempts at doing this:
SO Link
MSDN Link
These solutions basically update the progress bar after you add each row to the grid, though if you're trying to show progress for an actual database call I don't think you'll be able to be very accurate on that.
I think the main problem you'll have is that you won't have event hooks to let you know exactly where the time-consuming part of the binding comes into play. I'm assuming that it takes 5 seconds once you bind the data to the grid and that you're not counting the load time of actually pulling down the records.
Pre-BackgroundWorker
The BackgroundWorker class is basically just a convenience to you handling the threading yourself and invoking any progress back to the UI thread for you. You would have to spawn your own thread, and call BeginInvoke on your control once work is done to apply the data to the UI thread, since you can't make changes to the UI on any thread but the main one.
For the basics on how to implement a BackgroundWorker and a ProgressBar you can consult the examples given in the MSDN pages for ProgressBar and BackgroundWorker
As for actually making the percentage completed-property of your ProgressBar make sense, the key lies in finding a meaningful value to use as the argument for BackgroundWorker.ReportProgress(int). As you have probably noticed, in most tutorials and examples, people will normally just do a Thread.Sleep(100) inside a for-loop from 1 -> 100 and then send the iteration variable as the argument to ReportProgress.
The easiest solution for you is probably to set the ProgressBarStyle property to Marquee. That way your users can rest assured that your application hasn't frozen and that progress IS being made, although they won't know how long it will take for the operation to complete.
I recently started programming in WinForms using C#. I have a requirement where I need to search a set of folders and the sub-folders and display the status information to a textbox as I do the search like -
Looking up folder "C:\Windows"...
Found 8 files...
Copying file 1 of 8 to "D:\Temp"...
I have a method which does all the searching and stuff. I don't know how to display the status messages (like above) to a textbox periodically. Currently, the form waits for the method to be complete, and displays the messages all at once. I want them to be displayed one by one as the method progresses.
Thanks in advance.
To properly solve this your searching function will need to be running on a background thread. If the searching occurs on the UI thread it will block updates to the display preventing a periodic status message from being displayed.
The easiest way to do this in a WinForms application is to use a BackgroundWorker. It has a minimum of support for running a task on a background and returning progress information to the UI thread. Additionally there are a lot of tutorials available online to get you started with a solution.
use a BackgroundWorkerThread and the ReportStatus function. That way your UI will be responsive while the search takes place.
Run the method that performs searches on a separate thread (if you're not doing so already). It's quite easy using the async delegate features in .NET.
You can then write to the text box from the worker thread using Control.BeginInvoke() - you must do this because access to UI control sis affinitized to the single UI thread.
You can also create a background worker thread and use the ReportProgress method to notify the UI of updates. There's a fairly complete example of this approach available here that you can download and examine.
I have this massive nested loop scenario that is calling the DB and making HTTP requests to Basecamp API. At first it was a web app but it took much time to run the app so the user (billing department) would often quit out early or complain because it would take so long with no feedback and no way to cancel it. I wanted to make it more responsive and give it a Cancel button as well as a real time log, I also wanted to make it more controllable. I put it in forms so they could have control of every instance of it and have a cancel button and a real time log.
However when I hooked it all up with form buttons, multi-line text box to replace the response and error log, I cannot get anything to work! I added checks in the loop to break out if Cancel becomes pressed. However I can't even click cancel and the multiline TextBox will not live update when I .Text.Insert and then .Update() it. The whole app just sits there and spins... How do I get it to be responsive, accept button clicks during looping, and live update the multi-line TextBox?
NOTE: The thing compiles fine and I can step through it and it writes to a log file just fine so I can tell it's working after the fact that my form freezes up by looking at that log file.
Here is the code I am trying to update the multi-line TextBox with:
TimeSyncLog.Text.Insert(TimeSyncLog.Text.Length, "(((" + clientCode + ")))\n");
And here is the code for my loop breakout:
if(CancelPressed)
{
TimeSyncLog.Text.Insert(TimeSyncLog.Text.Length,"\n\nSYNC STOPPED BY USER.");
break;
}
But I can never click the Cancel button to toggle that boolean because the window says 'Not Responding'...
You shouldn't do any time consuming business logic on the UI thread.
you can use the BackgroundWorker class for those kind of things. it also support cancellation and progress report.
You can read about it here.
The UI thread should have only UI related changes in it. Semi-irrelevant to your question, there's an awesome threading tutorial here.
BackgroundWorker is a great class that uses the thread pool, though there are many options and things to consider when threading. If you want to cancel the thread, maybe nest an event in the GUI class so that the worker can subscribe to it, to handle the event of the 'Cancel' button being pressed. Perhaps that isn't the most efficient way, but I'm sure someone else around here can recommend a few more alternative routes. Hope this helps.