Environment: .net 3.5 WinForms application
I am looking for some ideas how to stop / interrupting a Windows Form application, e.g. when “something” takes too long.
A typical scenario is reading large amount of data from a backend system and the user shall be able to press some key immediately stopping the loading.
Normal events are not responsive enough, since the backend call somehow consumes so much time, they are not reacting in promptly fashion.
In my read methods I have added explicit checks – but I cannot add such checks in 3rd party frameworks. Also it is somehow not a very nice approach.
Maybe someone has an idea how to reliable and promptly stop some running methods. Is there an interrupt I can use?
Regards HW
Normal events are not responsive enough, since the backend call somehow consumes so much time
That's not how it works. Understand the "message loop" is pretty important, be sure to read up on it. In a nutshell, Windows can only tell your program that a button was clicked when the main thread of program is idle. Your main thread should always be idle, ready to jump into action when some bit of work needs to be done. Like painting your form or processing a keystroke. Or doing something when the user clicks the Cancel button.
Which means that something else needs to do the heavy lifting. A thread. By far the best way to get started in the troublesome world of threading is the BackgroundWorker class. It has a CancelAsync() method, explicitly designed to do what you want to do. Be sure to review the code sample provided in the MSDN Library article for this method.
Execute the long running code in a separate Thread.
Thread thread;
void StartLong()
{
thread = new Thread(SomeMethod);
thread.Start();
}
void SomeMethod()
{
//Long running code here.
}
void CancelButton_Click(object sender, EventArgs e)
{
//...
thread.Abort();
}
If you don't have control over the code that takes long to execute. All you can do do cancel it is to abort the thread. thread.Abort();
You should do "long" =eveything longer than 1/5sec operations in seperate threads.
The best way of topping an operation is giving it some kind of "context" with a variable wich tells the workerthread wether the user wants to abbord the operation or not.
If you have no control over the code doing the operation and the code is .net you may call Thread.Abort() but if the code is not .net the only thing you can do is callinfg the windows api function "terminatethread" but you may get some resource leaks and files not beeing closed so you should think of using a childprocess.
You may consider using the BackgroundWorker class, it abstracts out working directly with threads, so is a little easier to implement. You just create an instance of BackgroundWorker and attach some event handlers to it. Here is an example.
Related
We have C# application that crawling and executing code. But some time system stolp responding becouse code executing too long. How can we stop executing code after 10s that application will not stop responding any more.
The approaches taken to tackle this problem are dependent on the way you've designed your long running operation. So, without further details, I can only provide general pointers.
If your code takes to long to execute because you're not getting a response from a remote system (ie. db, website, etc) in time, then consider timeouts. If the API you use for making those remote calls, doesn't support timeouts, consider something like the CircuitBreaker pattern:
http://davybrion.com/blog/2009/07/protecting-your-application-from-remote-problems/
http://timross.wordpress.com/2008/02/10/implementing-the-circuit-breaker-pattern-in-c/
If it's simply that your application is doing a lot of work, make sure you do that work on a thread other than the UI thread, as Twitch said, to keep the UI responsive.
If you're using a very long loop doing internal work, then it could be worth checking repeatedly in that loop for a cancelation condition being met (this could be a flag set from a different thread or even elapsed time). This approach is called cooperative cancellation.
This article on the .Net 4.0 cancellation framework gives some good background, along with this article which it references.
You have to add some sort of way for the program to tell windows "no, it's not frozen, it's working", either by making all the processing and crawling in another thread, or by doing some form of notice, like printing something every few frames.
You can call Application.DoEvents to perform events while performing a long task in a GUI thread. That way it won't block the GUI.
You should consider running the long task in a thread itself though, since you get a lot more direct control then.
I was writing up a long, detailed question, but just scrapped it in favor of a simpler question that I didn't find an answer to here.
Brief app description:
I have a WPF app that spawns several threads, and each thread executes its own WF. What are some of the best ways to handle errors in the threads and WF that will allow user interaction from the GUI side? I definitely plan to handle any low level exceptions in the thread, because I don't want the thread to exit.
Summary of questions:
How have you implemented communication between WF and the thread that starts it? There is WorkflowTerminated, but I don't want the workflow to exit -- I need to fix the problem and let it continue. I assume the only option is using a FaultHandler, but was wondering if there's another way to do it without using an activity block. I am hoping there's a framework out there that I just haven't found yet.
The error from WF needs to get caught by the thread, which then needs to display the error in the GUI. The user will then make a logical choice for recovery, which should then be sent back to the thread, and then to WF. Again, is there something existing out there that I should take a look at?
Even buzzwords / keywords that accomplish what I am describing would be really helpful, and I can do the legwork on researching each of them. However, any additional insight is always welcome. :)
What's worked for me in multi-threaded WPF apps is to have the errant thread invoke a callback method that passes the exception and other info back to the UI thread. Callbacks can have return values, so if your thread can block while waiting for the user to respond, then that can work for you. Remember that the callback will run on the thread that calls it, so any UI updates have to be done via the control's dispatcher. You will have to decide whether all of the threads use the same callback and what kind of synchronization you'll need if there's a chance that multiple threads can throw exceptions simultaneously.
Here's how I ended up solving this problem. But first a little background info:
User clicks a button in the GUI that causes the candy packager to start running. This is done via a command binding in the ViewModel, which then calls a low-level function in the Model. The function in the model launches a thread and executes a state machine.
At some point, the machine will fail. When it does, I compile information about the error and possible (known) recovery methods. I put this into an object and then pass it to the GUI via a callback interface. In the meantime, the worker thread is stuck waiting for an Event to get set.
Eventually, the candy worker will notice the error and will click a button telling the system what to do. This results in two things: 1) it flags one of the recovery methods as the preferred one, and 2) sets the event. Now the worker thread continues on, checks for the preferred error recovery method and transitions into the respective state in the state machine.
This works very well (so far). The part I know is totally lame is the manner in which it checks for the preferred error recovery method. I am essentially setting a string variable, and then comparing this string to a list of known strings. Ultra lame, but I'm not sure of a better way to do this, other than using an enum. Does anyone have recommendations for me?
I've been working on the same project now since Christmas 2008. I've been asked to take it from a Console Application (which just prints out trace statements), to a full Windows App. Sure, that's fine. The only thing is there are parts of the App that can take several minutes to almost an hour to run. I need to multithread it to show the user status, or errors. But I have no idea where to begin.
I've aready built a little UI in WPF. It's very basic, but I'd like to expand it as I need to. The app works by selecting a source, choosing a destination, and clicking start. I would like a listbox to update as the process goes along. Much in the same way SQL Server Installs, each step has a green check mark by its name as it completes.
How does a newbie start multithreading? What libraries should I check out? Any advice would be greatly appreciated.
p.s. I'm currently reading about this library, http://www.codeplex.com/smartthreadpool
#Martin: Here is how my app is constructed:
Engine: Runs all major components in pre-defined order
Excel: Library I wrote to wrap COM to open/read/close/save Workbooks
Library: Library which understands different types of workbook formats (5 total)
Business Classes: Classes I've written to translate Excel data and prep it for Access
Db Library: A Library I've written which uses ADO.NET to read in Access data
AppSettings: you get the idea
Serialier: Save data in-case of app crash
I use everything from LINQ to ADO.NET to get data, transform it, and then output it.
My main requirement is that I want to update my UI to indicate progress
#Frank: What happens if something in the Background Worker throws an Exception (handled or otherwise)? How does my application recieve notice?
#Eric Lippert: Yes, I'm investigating that right now. Before I complicate things.
Let me know if you need more info. Currently I've running this application from a Unit Test, so I guess callig it a Console Application isn't true. I use Resharper to do this. I'm the only person right now who uses the app, but I'd like a more attractive interface
I don't think you specify the version of the CLR you are using, but you might check out the "BackgroundWorker" control. It is a simple way to implemented multiple threads.
The best part, is that it is a part of the CLR 2.0 and up
Update in response to your update: If you want to be able to update the progress in the UI -- for example in a progress bar -- the background worker is perfect. It uses an event that I think is called: ProgressChanged to report the status. It is very elegant. Also, keep in mind that you can have as many instances that you need and can execute all the instances at the same time (if needed).
In response to your question: You could easily setup an example project and test for your question. I did find the following, here (under remarks, 2nd paragraph from the caution):
If the operation raises an exception
that your code does not handle, the
BackgroundWorker catches the exception
and passes it into the
RunWorkerCompleted event handler,
where it is exposed as the Error
property of
System.ComponentModel..::.RunWorkerCompletedEventArgs.
Threading in C# from Joseph Albahari is quite good.
This page is quite a good summary of threading.
By the sound of it you probably don't need anything very complex - if you just start the task and then want to know when it has finished, you only need a few lines of code to create a new thread and get it to run your task. Then your UI thread can bumble along and check periodically if the task has completed.
Concurrent Programming on Windows is THE best book in the existence on the subject. Written by Joe Duffy, famous Microsoft Guru of multithreading. Everything you ever need to know and more, from the way Windows thread scheduler works to .NET Parallels Extensions Library.
Remember to create your delegates to update the UI so you don't get cross-threading issues and the UI doesn't appear to freeze/lockup
Also if you need a lot of notes/power points/etc etc
Might I suggest all the lecture notes from my undergrad
http://ist.psu.edu/courses/SP04/ist411/lectures.html
The best way for a total newcomer to threading is probably the threadpool. We'll probably need to know a little more about these parts to make more in depth recommendations
EDIT::
Since we now have a little more info, I'm going to stick with my previous answer, it looks like you have a loads of tasks which need doing, the best way to do a load of tasks is to add them to the threadpool and then just keep checking if they're done, if tasks need to be done in a specific order then you can simply add the next one as the previous one finishes. The threadpool really is rather good for this kind of thing and I see no reason not to use it in this case
Jason's link is a good article. Things you need to be aware of are that the UI can only be updated by the main UI thread, you will get cross threading exceptions if you try to do it in the worker thread. The BackgroundWorker control can help you there with the events, but you should also know about Control.Invoke (or Control.Begin/EndInvoke). This can be used to execute delegates in the context of the UI thread.
Also you should read up on the gotchas of accessing the same code/variables from different threads, some of these issues can lead to bugs that are intermittent and tricky to track down.
One point to note is that the volatile keyword only guarantees 'freshness' of variable access, for example, it guarantees that each read and write of the variable will be from main memory, and not from a thread or processor cache or other 'feature' of the memory model. It doesnt stop issues like a thread being interrupted by another thread during its read-update-write process (e.g. changing the variables value). This causes errors where the 2 threads have different (or the same) values for the variable, and can lead to things like values being lost, 2 threads having the same value for the variable when they should have different values, etc. You should use a lock/monitor (or other thread sync method, wait handles, interlockedincrement/decrement etc) to prevent these types of problems, which guarantee only one thread can access the variable. (Monitor also has the advantage that it implicitly performs volatile read/write)
And as someone else has noted, you also should try to avoid blocking your UI thread whilst waiting for background threads to complete, otherwise your UI will become unresponsive. You can do this by having your worker threads raise events that your UI subscribes to that indicate progress or completion.
Matt
Typemock have a new tool called Racer for helping with Multithreading issues. It’s a bit advanced but you can get help on their forum and in other online forums (one that strangely comes to mind is stackoverflow :-) )
I'm a newbie to multithreading as well, but I agree with Frank that a background worker is probably your best options. It works through event subscriptions. Here's the basics of how you used it.
First Instantiate a new background worker
Subscribed methods in your code to the background workers major events:
DoWork: This should contain whatever code that takes a long time to process
ProgressChanged: This is envoked whenever you call ReportProgress() from inside the method subscribed to DoWork
RunWorkerCompleted: Envoked when the DoWork method has completed
When you are ready to run your time consuming process you call the RunAsync() method of the background worker. This starts DoWork method on a separate thread, which can then report it's progress back through the ProgressChanged event. Once it completed RunWorkerComplete will be evoked.
The DoWork event method can also check if the user somehow requested that the process be canceled (CanceLAsync() was called)) by checking the value of the CancelPending property.
I have a WinForms app written in C# with .NET 3.5. It runs a lengthy batch process. I want the app to update status of what the batch process is doing. What is the best way to update the UI?
The BackgroundWorker sounds like the object you want.
The quick and dirty way is using Application.DoEvents() But this can cause problems with the order events are handled. So it's not recommended
The problem is probably not that you have to yield to the ui thread but that you do the processing on the ui thread blocking it from handling messages. You can use the backgroundworker component to do the batch processing on a different thread without blocking the UI thread.
Run the lengthy process on a background thread. The background worker class is an easy way of doing this - it provides simple support for sending progress updates and completion events for which the event handlers are called on the correct thread for you. This keeps the code clean and concise.
To display the updates, progress bars or status bar text are two of the most common approaches.
The key thing to remember is if you are doing things on a background thread, you must switch to the UI thread in order to update windows controls etc.
To beef out what people are saying about DoEvents, here's a description of what can happen.
Say you have some form with data on it and your long running event is saving it to the database or generating a report based on it. You start saving or generating the report, and then periodically you call DoEvents so that the screen keeps painting.
Unfortunately the screen isn't just painting, it will also react to user actions. This is because DoEvents stops what you're doing now to process all the windows messages waiting to be processed by your Winforms app. These messages include requests to redraw, as well as any user typing, clicking, etc.
So for example, while you're saving the data, the user can do things like making the app show a modal dialog box that's completely unrelated to the long running task (eg Help->About). Now you're reacting to new user actions inside the already running long running task. DoEvents will return when all the events that were waiting when you called it are finished, and then your long running task will continue.
What if the user doesn't close the modal dialog? Your long running task waits forever until this dialog is closed. If you're committing to a database and holding a transaction, now you're holding a transaction open while the user is having a coffee. Either your transaction times out and you lose your persistence work, or the transaction doesn't time out and you potentially deadlock other users of the DB.
What's happening here is that Application.DoEvents makes your code reentrant. See the wikipedia definition here. Note some points from the top of the article, that for code to be reentrant, it:
Must hold no static (or global) non-constant data.
Must work only on the data provided to it by the caller.
Must not rely on locks to singleton resources.
Must not call non-reentrant computer programs or routines.
It's very unlikely that long running code in a WinForms app is working only on data passed to the method by the caller, doesn't hold static data, holds no locks, and calls only other reentrant methods.
As many people here are saying, DoEvents can lead to some very weird scenarios in code. The bugs it can lead to can be very hard to diagnose, and your user is not likely to tell you "Oh, this might have happened because I clicked this unrelated button while I was waiting for it to save".
Use Backgroundworker, and if you are also trying to update the GUI thread by handling the ProgressChanged event(like, for a ProgressBar), be sure to also set WorkerReportsProgress=true, or the thread that is reporting progress will die the first time it tries to call ReportProgress...
an exception is thrown, but you might not see it unless you have 'when thrown' enabled, and the output will just show that the thread exited.
Use the backgroundworker component to run your batch processing in a seperate thread, this will then not impact on the UI thread.
I want to restate what my previous commenters noted: please avoid DoEvents() whenever possible, as this is almost always a form of "hack" and causes maintenance nightmares.
If you go the BackgroundWorker road (which I suggest), you'll have to deal with cross-threading calls to the UI if you want to call any methods or properties of Controls, as these are thread-affine and must be called only from the thread they were created on. Use Control.Invoke() and/or Control.BeginInvoke() as appropriate.
If you are running in a background/worker thread, you can call Control.Invoke on one of your UI controls to run a delegate in the UI thread.
Control.Invoke is synchronous (Waits until the delegate returns). If you don't want to wait you use .BeginInvoke() to only queue the command.
The returnvalue of .BeginInvoke() allows you to check if the method completed or to wait until it completed.
Application.DoEvents() or possibly run the batch on a separate thread?
DoEvents() was what I was looking for but I've also voted up the backgroundworker answers because that looks like a good solution that I will investigate some more.
I'm writing a J2ME application. One of the pieces is something that polls the contents of a directory periodically, and, if there are any new things, paints them on the screen. I've done this by having the UI form launch a polling thread with a pointer back to itself, and when the polling thread finds something it calls back to the form and calls a syncrhonized method to update it's display. This seems to work fine.
The question I have is this. In C#/.NET I know it is not nice to have non-UI threads updating the UI, and the correct way to handle this is to delegate it up to the UI thread.
E.g. the following:
public void DoSomeUIThing()
{
if (this.uiComponent.InvokeRequired)
{
this.uiComponent.Invoke(someDelegateThatCallsBackToThis);
}
else
{
this.uiComponent.Text = "This is the update I want to happen";
}
}
Is there a J2ME equivalent for how to manage this process? How about Java? Or does Java/J2ME just play nicer in regard to this? If not, how is this done?
[EDIT] It appears that Swing supports what I'm asking about via the SwingUtilities.invokeLater() and invokeAndWait() methods. Is there an equivalent framework for J2ME?
Regarding Java, what you are describing looks like a SwingWorker (worker thread).
When a Swing program needs to execute a long-running task, it usually uses one of the worker threads, also known as the background threads.
A Swing program includes the following kinds of threads:
Initial threads, the threads that execute initial application code.
The event dispatch thread, where all event-handling code is executed. Most code that interacts with the Swing framework must also execute on this thread.
Worker threads, also known as background threads, where time-consuming background tasks are executed.
Single-thread rule:
Once a Swing component has been realized, all code that might affect or depend on the state of that component should be executed in the event-dispatching thread.
When used in a J2EE context, you need to be careful when you are referencing a SwingWorker from an EJB.
Regarding J2ME, it depends if you are developing your application as a standard MIDlet that will run on any MIDP-enabled device, or for instance as a RIMlet, a CLDC-based application that uses BlackBerry-specific APIs and therefore will run only on BlackBerry devices.
Because unlike MIDP's UI classes, RIM's are similar to Swing in the sense that UI operations occur on the event thread, which is not thread-safe as in MIDP. To run code on the event thread, an application must obtain a lock on the event object, or use invokeLater() or invokeAndWait() – extra work for the developer, but sophistication comes with a price tag.
But for LCDUI, you can access a form from multiple threads.
There are many profiles of Java ME. If you mean MIDP then Display.runSerially is what you want.
For AWT (Swing) you would use EventQueue.invokeLater (SwingUtilities.invokeLater is only necessary due to Java 1.1 not having the EventQueue method - 1.2 is about to celebrate its tenth birthday). For the Common DOM API, use DOMService.invokeLater.
No matter what claims a GUI API may make about thread-safety they are probably wrong (some of the claims of Swing are removed in JDK7 because they are not implementable). In any case, application code unlikely to be thread-safe.
For j2me apps you probably want to keep it simple. The main thing is to touch UI components only in the event thread. The direct way of doing this is to use invokeLater or invokeAndWait. Depending on your libraries you won't have access to anything more than that. In general if these aren't provided in your platform it probably equates to there being no thread support and not being an issue. For example the blackberry does support it.
If you develop under SWT this is accomplished by means of asyncExec() method of Display object. You pass an object implementing Runnable so the UI thread executes the changes done in other thread.
This is an example borrowed from here
public void itemRemoved(final ModelEvent me)
{
final TableViewer tableViewer = this.viewer;
if (tableViewer != null)
{
display.asyncExec(new Runnable()
{
public void run()
{
tableViewer.remove(me.getItem());
}
}
}
}
I can attest that the MIDP UI toolkit is indeed thread-safe, as I have large MIDlets with complex GUI running on millions of phones made by almost every manufacturer, and I have never seen a problem in that regard.