Exit application when a process is in progress - c#

When a button is clicked in my form application all other controls are frozen,but if the process is time consuming I want to use a button to exit the application. How can I achieve this? Since all buttons are frozen.

You may try the BackgroundWorker. You can run the process without affecting the responsiveness of the UI. Moreover, you may cancel the process.
Referring to the example in the link, put your process logic is in backgroundWorker1_DoWork method, just follow the comment in the sample source code.

Related

showing status bar first to show progress

Im creating a c# windows form and ive come accross a problem.
When the window opens I am wanting to run a bit of code which can make the front console appear to freeze. The code runs fine but I want to show the status of the program in the status strip at the bottom of the page. I am running the code in the action Form.Shown. However the code does not update the status bar until everything is shown. I can change the label no problem.
How would I go about loading the window and then running the code and updating the status bar (like a background task)?
What areas would I need to look at to get this information?
You could use a BackgroundWorker to do this
Set the WorkerReportsProgress property to true and in the DoWork eventhandler raise the ReportProgress event
in the eventhandler for the ProgressChanged place your logic to update your progresbar
there is a example on msdn
You can use Multithreading to avoid freezing the forms. It means, you separate your form and the code (that you want to run in parallel) in different threads so that the form doesn't wait for the code completes. You can monitor the progress of the code via events.

How To Scan Files and Show Details of Current Scanning Without Making The Application Non-Responsive?

I am developing a desktop application for pdf file management using C#.
When I search any folder for *.pdf the application stops responding for some time, which is undesired behavior.
I am using XmlWriter to write data (i.e. file name,author name,subject). Also I have a label to show current scanning of file but it only show last file after complition of scanning.
This is a classic problem.
Basically the thread which displays the application is the thread which is doing all the work. So any updates/responsivness of the GUI will have to wait until its finished.
The solution to this is to make it multithreaded. The simplest way is to use a Background Worker thread which will do the writing searching and whatever, and just leave the main thread free.
http://www.dotnetperls.com/backgroundworker
If you can update your program, .NET 4.0 has new IO functions that return before finishing:
For example EnumerateFiles:
http://msdn.microsoft.com/en-us/library/dd383458.aspx
In addition to Haedrian's answer, I'd say that you could use the ProgressChanged event of BackGroundWorker to handle updating your progress indicators.
More specifically, you could raise that event with ReportProgress method, passing the name of the file curently scanning, and in the BackGroundWorker.ProgressChanged event handler you could update the label you want to use to show the file under scanning
If you don't like to create an extra thread you can call
Application.DoEvents();
in the loop. This keeps application responding and updates the label.

How can I flush buffer of form object properties BEFORE a Process.Start is executed?

On a button click, I make several changes to form elements (hiding some, showing some, bringing some to front, etc.). After those form element changes are made, I run an external process with a Process.Start(). However, even those those form element layout changes are sequentially coded before the Process.Start() call, they're not being executed/displayed BEFORE my Process.Start().
How do you force a flush of these layout changes that seem to be buffered?
You could try the Control.Invalidate(true) function on the control you want to be redrawn.
Here is a good post about the difference between Refresh, Update, and Invalidate
Based on the Post, I think you would want to use Refresh over Update to invalidate, then immediately update the control
Try either running the .Refresh method before the process.Start, or run Process.Start in a separate thread, such as:
System.Threading.ThreadPool.QueueNewWorkerItem(new System.Threading.WaitCallback(StartProcess));
void StartProcess(object state)
{
Process.Start(...);
}
By putting the start in a background thread, you allow .NET to update the UI before items in the background thread run. If the Process.Start is in the same thread as the UI, then the UI cannot refresh until all processes in that thread have finished running.
Found answer..
mainFormName.ActiveForm.Update();
Bang bang.

How do I keep my C# Windows Form Responsive while it churns loops?

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.

.Net Windows Forms - Limit form navigation while waiting on asynchronous work

On clicking a button, a query is executed in a background worker. It is asynchronous so that I can change the button to "Cancel" so the user can cancel the process if it runs longer than expected. This all works fine.
But, I do not want the user to be able to navigate away from this location to do other things on the form. They must be able to click the Cancel button or close the form, but nothing else.
Then I suggest you disable the other controls on the form when you begin processing your query, and when the background worker completes, re-enable them.
the best way to do this is to create a method like DisableControls() which contains the disable commands for all the other controls.
Once the async work is complete, on the callback, call a method like EnableControls() to revers the process.

Categories