Design pattern for cancelling or ignoring obsolete task on a worker thread - windows

I apologize if there's an obvious answer to this, but I just haven't located it yet.
I'm creating an application that loads some information from a database when the user navigates into an Explorer directory. I'm doing this on a background worker thread (using ATL's CWorkerThread), and calling SetEvent when the navigation occurs. When the background thread is done loading the data, it posts a custom message to a message-only window back on the UI thread. Then the UI thread can do stuff with the loaded info if it wants.
Of course, if the user navigates into a directory, and the worker-thread starts working, but the user quickly navigates away, the current worker-thread task is no longer necessary. So the task should be either cancelled if in progress, or if the worker thread has already posted its completion message to the UI thread, the UI thread should be prepared to check it and ignore it, since it's now stale.
My question is whether there is a nice design pattern and helpful example for this type of situation. I think I've seen situations in which a looping worker thread checks a boolean (like fCancelled) to see if it should still continue doing something. But how about when the completion message is already posted? Is there any standard way in which the worker thread and UI thread can communicate that the message is stale and should be disregarded?
Thank you very much for any input.

Related

Why not launch external crash dump handler at the time the application crashes?

I am in the process of designing a crash handler solution for one of our applications that creates a crash dump file using the MiniDumpWriteDump() function. While reading up on the topic I have seen the recommendations to invoke MiniDumpWriteDump() from an external process to maximize the chance that the dump file contains the correct information. The common solution seems to be to run a watchdog process in parallel to the application process. When the application crashes it somehow contacts the watchdog process, providing it with the information that is required to create the crash dump. Then the application goes to sleep until it is terminated by the watchdog process.
I can imagine such a watchdog process being run continually as a background service. This has many implications, starting with "who creates the service?", but also "which user does the service run as?", and "how does the application contact the service?" etc. It seems a pretty heavy-weight solution which I don't feel is appropriate for the scope of my task.
A simpler approach is suggested by this SO answer: Launch a guard process on application startup that is tightly coupled to the application process. This is pretty good, but it still leaves me with the tasks of 1) keeping the information somewhere in the application how I can contact the guard process in case of a crash; and 2) making sure to terminate the guard process if the application process shuts down normally.
The simplest solution of all would be to launch the crash dump handler process at the time the crash occurs, passing all the information that is required to create the crash dump as arguments to the process. This information consists of
The process ID of the application process that crashed
The thread ID of the thread that crashed
The adress of the EXCEPTION_POINTERS structure that describes the exception that caused the crash
This "fire and forget" approach is compelling because it does not require any state retention, nor any complicated over-time process management. In fact, the approach seems so overwhelmingly simple that I cannot help but feel that I am overlooking something.
What are the arguments against such an approach?
The main argument against the "fire and forget" approach, as I called it, is that it is not safe to launch a new process at a time when the application is already in a state where it is about to crash.
Because of that I went for the "guard process" approach. It brings a number of challenges with it, for which Hans Passant has outlined a solution.
I also added a bit of code in this answer that should help with deep-copying the all-important EXCEPTION_POINTERS data structure.
Using WER, as proposed in the comments, also looks like a good alternative to writing your own guard process. I must admit I have not investigated this any further, though.

MessageBox in worker thread

I have an application which calls into plugin DLLs. Some of those calls are done from a worker thread (i.e. not the UI thread), and just might popup a dialog with MessageBox. According to this (http://www.codeproject.com/Articles/121226/MessageBoxes-and-worker-threads) the effective UI thread is switched to the thread calling MessageBox. This "crashes" the application since the message pump stops receiving messages. Any way to switch back the UI thread to the correct one ? Any work-around ?
The culprit was AttachThreadInput, see this message.

creating window in child thread in vc++

I want to create a window and show some image display (like animation based on SetTimer()) on window created using CreateWindow() function. But it should be created on separate thread and should remain alive until user closes this. I tried but was unsuccessful.
EDITED
I just googled I found this link How To Create Windows in a Multithreaded Application but one thing i want to know when Window Procedure get invoked. if it is invoked by system then how i can call it from my child thread.
Windows (represented by HWNDs) in Windows have a thread affinity. Their WindowProc is always invoked in the context of the thread they are created with.
As such, they are a convenient way to serialize calls between threads as the PostMessage and SendMessage APIs can be called from any thread in the application, but the WindowProc will get executed in the context of the original creating thread.
Because WM_TIMER messages posted to message queues are the mechanism by which SetTimer works, again you need to be careful when calling SetTimer in a multithreaded app - The timer messages will be processed by the calling thread (if the hwnd parameter is NULL) or the window's thread.
You also, as a result, have to be careful to put a message loop on every thread that might create windows, or want to process timers.
Keep your user-interface on the main Windows thread. Setting a timer using the Windows API doesn't require an additional thread (as your WndProc will get the timer message WM_TIMER).
Even if you have a long running task to perform that might necessitate the use of an additional thread, keep the window on the main thread, do your work in the worker-thread and post back to the main thread with updates.

outlook add-in, slowing down outlook UI

I have written an outlook add-in to filter spam. The issue is that when the add-in is doing its job of processing a message, and especially with a large attachment that it is procesing / reading through, it is taking a lot of time and because of this the main outlook UI is un-responsive and users cannot do anything with the UI.
Is there an asynchrounous way of running the add-in processing, so that the outlook UI remains OK.
The add-in does a lot of things dueing its procesing of each message and hence it takes a lot of time.
Creating another thread won't help you if the bulk of the time is being spent in the Outlook API. Due to the threading model in Outlook, accessing the object model from another thread will cause the call to be marshalled to the main thread which means now your UI is still frozen and your background thread is blocking.
If most of the work is spent doing things that don't touch the Outlook object model, you'll probably see a significant improvement spinning off a separate worker thread (or thread pool) to process the attachments you've saved.
It's just like with any other program basically. If you need to do something outside of the main thread do so (i.e. create another thread). There's no Outlook-specific API or framework, though.
You have to be extra careful about exception handling though. Unhandled exceptions escaping from a thread can have the weirdest results (though in most cases Outlook will simply crash).
Also, if at all possible you should try to avoid or at least drastically limit accessing the Outlook Object Model from within your processing thread.
Finally, another thing you should make sure of is that you explicitly call CoInitializeEx / CoUninitialize specially for your new thread if it in any way directly or indirectly uses COM-related functions.

Does Application.ApplicationExit event work to be notified of exit in non-Winforms apps?

Our code library needs to be notified when the application is exiting. So we have subscribed to the System.Window.Forms.Application.ApplicationExit event. This works nicely for Winforms apps, but does it also work for other types of applications such as console apps, services, and web apps (such as ASP.NET)? The namespace would suggest that it doesn't, and it presumably gets raised when Application.Exit() is called (explicitly or implictly), which may not be correct to call for these other cases.
Is there some other event which would be better in these other cases or which would be more universal (great if it works for Winforms, too)? For example, is there an event for when Environment.Exit() is called (console app)?
I found a mention of an Exited event in System.Diagnostic.Process, but this appears to be for monitoring the exit of another process, and it does not appear to be received by a process about itself (for example, Process.GetCurrentProcess().Exited += Process_Exited; Process.GetCurrentProcess().EnableRaisingEvents = true;). I would think it might only be raised after the process has actually exited, so that wouldn't work.
This is particularly for .NET 2.0 and C#.
We finally found more about this (but by then my machine had been rebuilt and lost the cookies to my unregistered profile here; hopefully, it will let met post this answer).
Further investigation eventually found a few more events which we have found helpful:
System.Windows.Forms.Application.ThreadExit - Fires when a message loop exits
System.Windows.Forms.Application.ApplicationExit - Fires when all message loops exit
System.AppDomain.CurrentDomain.DomainUnload - Fires when a domain other than the default exits
System.AppDomain.CurrentDomain.ProcessExit - Fires when the default app domain exits
System.AppDomain.CurrentDomain.UnhandledException - Fires when an uncaught exception occurs, ending the app.
Only one of the DomainUnload or ProcessExit events are possible for a given app domain, depending on whether it is the default (top-level) domain for the process or was created as a subdomain (eg. on a web server). If an application doesn't know which it might be (as in our case), it needs to subscribe to both if it wants to catch the actual unload for itself. Also, it appears that UnhandledException (which as of .NET2.0 is always fatal) may prevent the other two events, so that may be a third case to handle. These three events should work for any .NET application.
There is a caveat that the execution time for ProcessExit is bounded (about 4 seconds?), so it may not be possible to do extensive "final" work in that event handler. It needs to be something which can be done quickly.
The Application events only apply to WinForms applications (we suspect they may not apply in pure WPF applications, however). The naming can be misleading because they are named for their most basic normal usage which has certain assumptions. ThreadExit does not relate to the actual System.Threading.Thread but rather to the message loop (Application.Run())) of a UI thread, and ApplicationExit similarly relates to the collection of application Forms on one or more UI threads. Normally, once the call to Application.Run() returns, called from the entry method of a thread, the entry method quickly concludes and the thread itself then ends. And once all UI threads have exited, a WinForms app is usually all done and exits.
Another event of note is the System.Windows.Forms.Application.ThreadException event. A Windows message loop can be configured to catch exceptions which occur in handling a message and send this event rather than let them be uncaught (and thus fatal) exceptions. Catching these exceptions allows the message loop (and that UI thread) to continue running (after aborting the current message handler). There can be only one subscriber to this event at any time for a given thread (subscriptions overwrite any previous subscriber), and it must be configured before any Form is created and subscribed before entering the message loop. See the MSDN help for this event and System.Windows.Forms.Applicaton.SetUnhandledExceptionMode() for more info.

Resources