zoukankan      html  css  js  c++  java
  • 如何:创建和终止线程(C# 编程指南MSDN)

    此示例演示如何创建辅助线程,并用它与主线程并行执行处理。还将演示如何使一个线程等待另一个线程,并正确地终止线程。有关多线程处理的背景信息,请参见托管线程处理使用线程处理(C# 编程指南)

    该示例创建一个名为 Worker 的类,该类包含辅助线程将执行的方法 DoWork。这实际上是辅助线程的 Main 函数。辅助线程将通过调用此方法来开始执行,并在此方法返回时自动终止。DoWork 方法如下所示:

    public void DoWork()
    {
        
    while (!_shouldStop)
        {
            Console.WriteLine(
    "worker thread: working");
        }
        Console.WriteLine(
    "worker thread: terminating gracefully.");
    }

    Worker 类包含另一个方法,该方法用于通知 DoWork 它应当返回。此方法名为 RequestStop,如下所示:

    public void RequestStop()
    {
        _shouldStop 
    = true;
    }

    RequestStop 方法只是将 true 赋给 _shouldStop 数据成员。由于此数据成员由 DoWork 方法来检查,因此这会间接导致 DoWork 返回,从而终止辅助线程。但是,您应当注意:DoWorkRequestStop 将由不同线程执行。DoWork 由辅助线程执行,而 RequestStop 由主线程执行,因此 _shouldStop 数据成员声明为 volatile,如下所示:

    private volatile bool _shouldStop;

    volatile 关键字用于通知编译器,将有多个线程访问 _shouldStop 数据成员,因此它不应当对此成员的状态做任何优化假设。有关更多信息,请参见volatile(C# 参考)

    通过将 volatile_shouldStop 数据成员一起使用,可以从多个线程安全地访问此成员,而不需要使用正式的线程同步技术,但这仅仅是因为 _shouldStopbool。这意味着只需要执行单个原子操作就能修改 _shouldStop。但是,如果此数据成员是类、结构或数组,那么,从多个线程访问它可能会导致间歇的数据损坏。假设有一个更改数组中的值的线程。Windows 会定期中断线程,以便允许其他线程执行。因此,此线程会在分配某些数组元素之后和分配其他元素之前被停止。由于数组现在有了一个程序员从不想要的状态,因此,读取此数组的另一个线程可能会失败。

    在实际创建辅助线程之前,Main 函数会创建一个 Worker 对象和 Thread 的一个实例。线程对象被配置为:通过将对 Worker.DoWork 方法的引用传递给 Thread 构造函数,来将该方法用作入口点,如下所示:

    Worker workerObject = new Worker();
    Thread workerThread 
    = new Thread(workerObject.DoWork);

    此时,尽管辅助线程对象已存在并已配置,但尚未创建实际的辅助线程。只有当 Main 调用 Start 方法后,才会创建实际的辅助线程:

    workerThread.Start();

    此时,系统将启动辅助线程的执行,但这是在与主线程异步执行的。这意味着 Main 函数将在辅助线程进行初始化的同时继续执行代码。为了确保 Main 函数不会尝试在辅助线程有机会执行之前将它终止,Main 函数将一直循环,直到辅助线程对象的 IsAlive 属性设置为 true

    while (!workerThread.IsAlive);

    下一步,通过调用 Sleep 来将主线程停止片刻。这确保了辅助线程的 DoWork 函数在 Main 函数执行其他任何命令之前,在 DoWork 方法内部执行若干次循环:

     Thread.Sleep(1);

    在 1 毫秒之后,Main 将通知辅助线程对象,它应当使用 Worker.RequestStop 方法(前面已介绍)自行终止:

    workerObject.RequestStop();

    还可以通过调用 Abort 从另一个线程中终止某个线程。这将强行终止受影响的线程,即使该线程尚未完成其任务,并且未提供清理资源的机会。此示例中显示的技术是首选方法。

    最后,Main 函数对辅助线程对象调用 Join 方法。此方法导致当前线程阻塞或等待,直到对象所表示的线程终止。因此,直到辅助线程返回后,Join 才会返回,然后自行终止:

    workerThread.Join();

    此时,只有执行 Main 的主线程还存在。它会显示一条最终消息,然后返回,从而使主线程也终止。

    下面是完整的示例。

     示例:

    using System;
    using System.Threading;

    public class Worker
    {
        
    // This method will be called when the thread is started.
        public void DoWork()
        {
            
    while (!_shouldStop)
            {
                Console.WriteLine(
    "worker thread: working");
            }
            Console.WriteLine(
    "worker thread: terminating gracefully.");
        }
        
    public void RequestStop()
        {
            _shouldStop 
    = true;
        }
        
    // Volatile is used as hint to the compiler that this data
        
    // member will be accessed by multiple threads.
        private volatile bool _shouldStop;
    }

    public class WorkerThreadExample
    {
        
    static void Main()
        {
            
    // Create the thread object. This does not start the thread.
            Worker workerObject = new Worker();
            Thread workerThread 
    = new Thread(workerObject.DoWork);

            
    // Start the worker thread.
            workerThread.Start();
            Console.WriteLine(
    "main thread: Starting worker thread");

            
    // Loop until worker thread activates.
            while (!workerThread.IsAlive);

            
    // Put the main thread to sleep for 1 millisecond to
            
    // allow the worker thread to do some work:
            Thread.Sleep(1);

            
    // Request that the worker thread stop itself:
            workerObject.RequestStop();

            
    // Use the Join method to block the current thread 
            
    // until the object's thread terminates.
            workerThread.Join();
            Console.WriteLine(
    "main thread: Worker thread has terminated.");
        }
    }

    输出如下:

    main thread: starting worker thread
    worker thread: working
    worker thread: working
    worker thread: working
    worker thread: working
    worker thread: working
    worker thread: working
    worker thread: working
    worker thread: working
    worker thread: working
    worker thread: working
    worker thread: working
    worker thread: terminating gracefully
    main thread: worker thread has terminated
  • 相关阅读:
    AX 2012 Security Framework
    The new concept 'Model' in AX 2012
    How to debug the SSRS report in AX 2012
    Using The 'Report Data Provider' As The Data Source For AX 2012 SSRS Report
    Deploy SSRS Report In AX 2012
    AX 2012 SSRS Report Data Source Type
    《Taurus Database: How to be Fast, Available, and Frugal in the Cloud》阅读笔记
    图分析理论 大纲小结
    一文快速了解Posix IO 缓冲
    #转载备忘# Linux程序调试工具
  • 原文地址:https://www.cnblogs.com/greatandforever/p/1597507.html
Copyright © 2011-2022 走看看