我有一个Windows窗体和一个带有两个简单方法的类,这些方法以非确定的方式递归运行(这意味着它不知道将调用哪个递归,两者都可以调用另一个)...现在,在此期间有一些点我希望暂停执行并等待用户点击“下一步”按钮的递归。只有在按下按钮后,递归功能才会继续。该类在一个单独的线程上运行,因此它不会阻止UI。
在暂停期间,Form只会从类中检索值并将其显示在列表框中。然后在按下按钮后,递归继续,直到下一个Pause()。我需要这个,以便用户可以逐步查看递归中发生的情况。此外,我需要能够将Pause()放在递归方法的任何位置(甚至多次),而不会产生任何副作用......
我想到的唯一方法是调用Pause()方法,其中循环检查一些锁定标志然后休眠一段时间(然后按钮会设置标志),但我对Thread有一些不好的经历Windows窗体中的.Sleep()(锁定UI)所以我正在寻找其他选项。
有没有干净的方法可以做到这一点?
答案 0 :(得分:6)
使用初始化为ManualResetEvent
的{{1}},使其开始设置。在一个方法或另一个方法(或两者)的知名地方,等待事件。大多数情况下,事件将被设置为后台线程将立即继续。但是,当用户单击“暂停”时,重置事件,导致后台线程在下次到达事件时阻塞。当用户下次单击“恢复”时,设置事件,允许后台线程再次继续。
在这种情况下,UI线程没有理由阻止。
答案 1 :(得分:2)
使用AutoResetEvent对象。
从你的线程调用它上面的.WaitOne方法暂停它,并从你的按钮调用它上面的.Set方法取消它。
答案 2 :(得分:1)
这是以非标准方式使用互斥锁的好地方。只需让你的后台线程获取并释放互斥锁,当它处于可以等待的位置时。
让你的GUI线程在想要阻止后台线程时使用Mutex,并在它可以运行时释放它。
这样后台线程会在它应该的时候等待,并且当它被允许运行时,它将简单地进出Mutex。
将“运行权”视为关键部分正在保护的资源。
像这样// 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();