Teejay
Teejay

Reputation: 7469

Suspending worker-thread and wait for user interaction on main-thread

I have a main UI thread that starts a SQL batch on a working thread.

The batch may generate some errors (blocking) or warnings (non-blocking).

In the first case, I finally rollback the transaction and exit thread.

In the second case, I want the user to review warning messages in the middle of the SQL batch:

  1. some data are processed
  2. some warnings are generated
  3. user reviews these messages
  4. user decides to continue or stop the batch
  5. batch resumes or stops

I could possibly make a ShowDialog() directly from the working thread, but I don't like this solution, since this is not an UI thread.

My idea was to inform the main UI thread about the situation ("Warnings have been generated") and sleep the working thread for a fixed amount of time (say 500ms). A tristate (bool?) is checked every time the thread wakes up, if it has not a value, thread is slept again.

When the user reviewed warnings and possibly decides to continue, the boolean is set and the next time the working thread will wake up, it will know if continue or safely abort (rollback) the batch.

Is this a so bad design-pattern?

Upvotes: 1

Views: 127

Answers (3)

Jon
Jon

Reputation: 437386

If you change the "wakeup" mechanism the concept is not bad.

Instead of a bool? and periodically waking up the worker on its own it would be better to use a bool and a ManualResetEvent. The worker notifies the UI and waits on the event (immediately blocking). The UI interacts with the user, sets the bool appropriately and signals the event (releasing the worker, which inspects the bool value and acts accordingly).

Of course the above can be implemented in a variety of manners, and the implementation leaves quite a bit of room for engineering. On one end of the scale you could have tightly coupled code with a raw flag and event, while on the other you could have an abstract "feedback service" that the worker queries.

This would enable you to swap one implementation of the feedback service for another, allowing among others:

  1. Presenting a "do this for all warnings" option; if it's selected, the feedback service stops showing UI for the requests and instead answers them internally.
  2. Executing an operation in "silent mode": the feedback service is configured to answer requests without showing UI (e.g. always saying "continue").

Upvotes: 4

Jarek
Jarek

Reputation: 3379

Instead of using bool?, why not go with some locking mechanism? ManualResetEvent for example could block the thread until user decides. Than his decision could set this event, causing thread to continue doing work. The way it should continue working should be passed in another variable, to make clear distinction between mechanism for blocking and information on how to continue exectution.

Upvotes: 1

Asha
Asha

Reputation: 11232

I would use Events to do this. Like this:

  1. Create an AutoResetEvent as the class member variable
  2. When use interaction is required, reset the event first
  3. Inform main UI thread
  4. Wait on the event

In Main Thread:

  1. Show the warning/error.
  2. Store what is user's choice.
  3. Set the event.

Now, the worker thread will wakes up and gets the main thread's result (what user selected) and proceeds.

Upvotes: 2

Related Questions