hf

导航

 

本来可以用Thread.Suspend暂停的,但它被弃用了,微软建议用Monitor, Mutex, Event, Semaphore等来做线程同步或保护资源。

有时候我们只是想单纯的暂停一个线程,例如一个爬虫程序,很久爬不完暂停下吧(也许没什么用处......),可以用下边的办法。

先定义一些线程状态:

public enum TaskStatus {
    Stopped,
    Running,
    Paused,
    Stopping,
    Pausing,
}

在Pause方法里改变当前状态:

public void Pause() {
    if (taskStatus != TaskStatus.Running)
        return;
    taskStatus = TaskStatus.Pausing;
}

再有一个方法处理状态改变请求:

protected bool ResponseStatusChange() {
    if (TaskStatus == TaskStatus.Stopped) {
        return true;
    }
    while (TaskStatus != TaskStatus.Running) {
        switch (TaskStatus) {
            case TaskStatus.Pausing:
                TaskStatus = TaskStatus.Paused;
                break;
            case TaskStatus.Stopping:
                TaskStatus = TaskStatus.Stopped;
                return true;
        }
        Thread.Sleep(1000);
    }
    return false;
}

在这个方法里如果状态为TaskStatus.Pausing就一直循环等待,如果为Stopped就返回True,Running就返回False。

这里就是用循环等待来模拟暂停。当继续时状态改为Running于是返回继续执行。

可以把这个方法放在每次循环里来检查状态。

封装在一个类里完整代码如下:

public abstract class Task{
    public TaskStatus TaskStatus {
        get;
        protected set;
    }
    protected abstract void DoStart();
    /// <summary>
    /// 响应状态改变请求,如果停止返回True
    /// </summary>
    /// <returns></returns>
    protected bool ResponseStatusChange() {
        if (TaskStatus == TaskStatus.Stopped) {
            return true;
        }
        while (TaskStatus != TaskStatus.Running) {
            switch (TaskStatus) {
                case TaskStatus.Pausing:
                    TaskStatus = TaskStatus.Paused;
                    break;
                case TaskStatus.Stopping:
                    TaskStatus = TaskStatus.Stopped;
                    return true;
            }
            Thread.Sleep(1000);
        }
        return false;
    }

    public void Start() {

        switch (TaskStatus) {
            case TaskStatus.Pausing:
            case TaskStatus.Stopping:
                return;
            case TaskStatus.Paused:
                TaskStatus = TaskStatus.Running;
                break;
            case TaskStatus.Stopped:
                TaskStatus = TaskStatus.Running;
                var thread = new Thread(DoStart);
                thread.Start();
                return;
            case TaskStatus.Running:
                return;
        }
    }

    public void Pause() {
        if (TaskStatus != TaskStatus.Running)//Only When Running
            return;
        TaskStatus = TaskStatus.Pausing;
    }

    public void Stop() {
        if (TaskStatus == TaskStatus.Stopped)
            return;
        TaskStatus = TaskStatus.Stopping;
    }
}

像下边这样使用:

public class MyTask : Task {
    protected override void DoStart() {
        //...
        while (true) {//...
            if (ResponseStatusChange()) {
                return;
            }//...
        }
    }
    static void Main() {
        var task = new MyTask();
        task.Start();
        task.Pause();
        task.Start();
        task.DoStart();
    }
}
posted on 2010-07-06 17:54  hf  阅读(1690)  评论(0)    收藏  举报