我做了一些研究,环顾四周,似乎做到这一点的方法是使用AutoResetEvent。我很快将它们放在一起,它似乎可以工作并且似乎是线程安全的。可以给我一些反馈吗?
class Program
{
private Thread workerThread;
private AutoResetEvent aResetEvent;
private bool _continueProcessing;
private bool active;
private Object locker = new Object();
public Program()
{
workerThread = new Thread(DoSomeProcessing);
workerThread.IsBackground = true;
aResetEvent = new AutoResetEvent(false);
}
public bool ContinueProcessing
{
get
{
lock (locker)
{
return _continueProcessing;
}
}
set
{
if (value)
{
aResetEvent.Set();
}
else
{
aResetEvent.Reset();
}
lock (locker)
{
_continueProcessing = value;
}
}
}
public void DoSomeProcessing()
{
int i = 0;
try
{
while (active)
{
aResetEvent.WaitOne();
// do some work and sleep
lock (locker)
{
if (ContinueProcessing)
{
aResetEvent.Set();
}
}
}
}
catch(ThreadInterruptedException tie)
{
Console.WriteLine("Shutting down.");
}
// any shutdown processing
}
public void StopProcessing()
{
workerThread.Interrupt();
workerThread.Join();
}
public void PauseProcessing()
{
ContinueProcessing = false;
}
public void Continue()
{
ContinueProcessing = true;
}
public void StartProcessing()
{
ContinueProcessing = true;
active = true;
}
}
编辑:
你好,我们又见面了。我已经使用了反馈,对自己的实现感到更加满意。我只想添加一件事,当我暂停时,我想等一下以确保线程已暂停并且不再工作。那可能吗?也许我应该只用start和stop代替暂停和恢复,然后在stop上执行thred.join()。评论?
最佳答案
一旦退出被调用,ManualResetEvent将被释放,并且在调用实例方法时可能会引发异常。 ->在某些情况下这可能不是理想的
class Program {
static void Main(string[] args) {
//NOTE: if worker goes out of scope it will be collected -> ex: promote to field in real use
Worker worker = new Worker();
System.Threading.Thread workerThread = new System.Threading.Thread(new System.Threading.ThreadStart(worker.DoWork));
workerThread.IsBackground = true;
workerThread.Start();
// test
worker.Resume();
System.Threading.Thread.Sleep(2000);
worker.Pause();
System.Threading.Thread.Sleep(2000);
worker.Resume();
System.Threading.Thread.Sleep(2000);
worker.Exit();
System.Threading.Thread.Sleep(5000);
}
}
public class Worker {
private readonly System.Threading.ManualResetEvent _Gate;
private bool _IsActive;
public Worker() {
_Gate = new System.Threading.ManualResetEvent(false);
_IsActive = true;
}
public void DoWork() {
while (IsActive) {
_Gate.WaitOne();
// do work
// can yield the thread
System.Threading.Thread.Sleep(1);
}
// dispose
_Gate.Close();
}
private bool IsActive {
get {
lock (_Gate) {
return _IsActive;
}
}
}
public void Pause() {
_Gate.Reset();
}
public void Resume() {
_Gate.Set();
}
public void Exit() {
lock (_Gate) {
_IsActive = false;
}
}
}
关于.net - .Net Thread.Suspend已过时。寻找替代品,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2251718/