开发者

How to make Background thread pause and then continue on button click?

开发者 https://www.devze.com 2022-12-15 03:28 出处:网络
I have a Windows Form and a class with two simple methods that run recursively in a nondeterministic way (meaning that it\'s unknown which recursion will be called, both can call the other)... Now, th

I have a Windows Form and a class with two simple methods that run recursively in a nondeterministic way (meaning that it's unknown which recursion will be called, both can call the other)... Now, there are some points during that recursion at which I want to pause the execution and wait for a user to click on the "Next Step" button. Only after the button is pressed should the recursive functions continue. The class runs on a separate thread so it doesn't blo开发者_StackOverflow社区ck the UI.

During that pause, the Form would simply retrieve the value from the class and display it in a listbox. Then after the button is pressed, the recursion continues until the next Pause(). I need this so the user can see what is happening in the recursion step by step. Also I need to be able to put Pause() anywhere in the recursive method (even multiple times) without causing any side-effects...

The only way that comes to my mind is to call Pause() method in which a loop checks some locked flag and then sleeps for some time (the button would then set the flag), but I had some bad experiences with Thread.Sleep() in Windows Forms (locking the UI) so I am looking at another options.

Is there any clean way to do this?


Use a ManualResetEvent that is initialized to true, so it begins set. At a well-known place in one method or the other (or both), wait for the event. Most of the time, the event will be set so the background thread will continue immediately. When the user clicks Pause, however, reset the event, causing the background thread to block the next time it reaches the event. When the user next clicks "Resume", set the event, allowing the background thread to continue again.

There's no reason that the UI thread should ever block in this scenario.


Use a AutoResetEvent object.

Call the .WaitOne method on it from your thread to pause it, and call the .Set method on it from your button to unpause it.


This is a good place to use a Mutex in a non-standard way. Just have your background thread take and release the Mutex when it's in a position where it's ok to wait.

Have your GUI thread take the Mutex when it wants to block the background thread, and release it when it's ok for it to run.

That way the background thread will wait when it should, and will simple blaze in and out of the Mutex when it's allowed to run.

Think of the 'right to run' as a resource that the critical section is protecting.

like this

// this object has to be visible to both threads
System.Threading.Mutex mtx = new Mutex();

// worker thread does this wherever it's ok for it to pause
mtx.WaitOne();
mtx.ReleaseMutex();

// main thread does this to pause the worker
Mtx.WaitOne();

// main thread does this this to unpause it.
mtx.ReleaseMutex();
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号