一旦调用停止,就防止线程进一步处理

时间:2012-05-11 07:55:47

标签: c# multithreading windows-services thread-safety thread-abort

我有一个Windows服务,它将启动和停止执行一些正在使用Threads保持的进程。

我有两个课程如下:

public class PerformTask
{
    Thread _thread = null;
    public void StartTask()
    {
        _thread = new Thread(new ThreadStart(DoSomeWork));
        _thread.Start();
    }

    public void DoSomeWork()
    {
        // Do Some Work
        _thread = null;
    }

    public void Abort()
    {
        if (_thread != null)
        {
            try
            {
                _thread.Abort();
            }
            catch (ThreadAbortException) {}
        }
    }
}

public class Engine
{
    List<PerformTask> _task = new List<PerformTask>();
    public void Start()
    {
        var task = new PerformTask();
        _task.Add(task);
        // Add task to the timed action queue
        _actionQueue.Add(s => task.StartTask(), TimeSpan.FromSeconds(10));
    }

    public void Stop()
    {
        _task.ForEach(task => task.Abort());
        _task.Clear();
        _actionQueue.Stop();
        _actionQueue.Clear();
    }
}

_actionQueue是一个自定义的源代码,用于在指定的重复时间间隔执行指定的操作。所有操作都保存在队列中,并以指定的时间间隔调用。

现在,Windows服务的OnStart和OnStop方法将分别调用Engine类的Start和Stop方法。

我想要的是当Windows服务停止时,所有正在运行的线程都应该停止处理/执行。

但是,这里发生的事情是在创建新线程实例的时候我有一个Windows服务,它将启动和停止执行一些正在使用Threads保持的进程。

我有两个课程如下:

public class PerformTask
{
    Thread _thread = null;
    public void StartTask()
    {
        _thread = new Thread(new ThreadStart(DoSomeWork));
        _thread.Start();
    }

    public void DoSomeWork()
    {
        // Do Some Work
        _thread = null;
    }

    public void Abort()
    {
        if (_thread != null)
        {
            try
            {
                _thread.Abort();
            }
            catch (ThreadAbortException) {}
        }
    }
}

public class Engine
{
    List<PerformTask> _task = new List<PerformTask>();
    ActionQueue _actionQueue = new ActionQueue();
    public void Start()
    {
        foreach(.....)
        {
            var task = new PerformTask();
            _task.Add(task);
            // Add task to the timed action queue
            _actionQueue.Add(s => task.StartTask(), TimeSpan.FromSeconds(10));
        }
        _actionQueue.Start();
    }

    public void Stop()
    {
        _task.ForEach(task => task.Abort());
        _task.Clear();
        _actionQueue.Stop();
        _actionQueue.Clear();
    }
}

ActionQueue是一个自定义的源代码,用于在指定的重复时间间隔内执行指定的操作。所有操作都保存在队列中,并以指定的时间间隔调用。

现在,Windows服务的OnStart和OnStop方法将分别调用Engine类的Start和Stop方法。

我想要的是当Windows服务停止时,所有正在运行的线程都应该停止处理/执行。

但是,这里发生的事情是在我调用的时候,在StartTask方法中创建了新的线程实例     _task.ForEach(task =&gt; task.Abort()) 我没有正确的Thread实例,也就是所有的实例     _thread = new Thread(....); 没有被访问,因为同一个PerformTask类会有多个队列。

注意:我无法更改ActionQueue。

  1. Abort方法是停止线程的正确方法吗?

  2. 如何停止所有线程(包括源代码创建的Thread类的所有实例)?

1 个答案:

答案 0 :(得分:1)

通常你会创建一个WaitHandle(例如ManualResetEvent):

ManualResetEvent stopAllThreads = new ManualResetEvent(false);

所以事件是“未设置”。更改线程方法中的循环,使它们循环,直到完成所有工作或设置手动重置事件。

while (!stopAllThreads.WaitOne(50))

或类似。

然后,在服务的OnStop方法中,您只需设置事件(不要忘记在OnStart中再次重置它,否则在重新启动服务时线程将不会再次运行):

stopAllThreads.Set();

并等待所有线程完成。

实际上,中止线程并不是阻止线程的好方法 - 你应该总是去做类似的事情。