简体   繁体   中英

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM