zoukankan      html  css  js  c++  java
  • ylbtech-LanguageSamples-Threading(线程处理)

    ylbtech-Microsoft-CSharpSamples:ylbtech-LanguageSamples-Threading(线程处理)

     

    1.A,示例(Sample) 返回顶部

    “线程处理”示例

    本示例演示了下面的线程处理技术。有关更多信息,请参见线程处理(C# 编程指南) 。

    • 创建、启动和终止线程

    • 使用线程池

    • 线程同步和互交

    安全说明

    提供此代码示例是为了阐释一个概念,它并不代表最安全的编码实践,因此不应在应用程序或网站中使用此代码示例。对于因将此代码示例用于其他用途而出现的偶然或必然的损害,Microsoft 不承担任何责任。

    在 Visual Studio 中生成并运行“线程处理”示例

    1. 在“解决方案资源管理器”中,右击“ThreadStartStop”项目并单击“设为启动项目”。

    2. 在“调试”菜单上,单击“开始执行(不调试)”。

    3. 对于 ThreadPool 和 ThreadSync,分别重复上述步骤。

    从命令行生成并运行“线程”示例

    1. 使用“更改目录”命令转到“Threads”目录。

    2. 键入以下命令:

      cd ThreadStartStop
      csc ThreadStartStop.cs
      ThreadStartStop
    3. 键入以下命令:

      cd ..ThreadPool
      csc ThreadPool.cs
      ThreadPool
    4. 键入以下命令:

      cd ..ThreadSync
      csc ThreadSync.cs
      ThreadSync
    1.B,ThreadStartStop 示例代码(Sample Code)返回顶部

    1.B.1, ThreadStartStop.cs

    // 版权所有(C) Microsoft Corporation。保留所有权利。
    // 此代码的发布遵从
    // Microsoft 公共许可(MS-PL,http://opensource.org/licenses/ms-pl.html)的条款。
    //
    //版权所有(C) Microsoft Corporation。保留所有权利。
    
    using System;
    using System.Threading;
    
    public class Worker
    {
        // 启动线程时调用此方法。
        public void DoWork()
        {
            while (!_shouldStop)
            {
                Console.WriteLine("worker thread: working...");
            }
            Console.WriteLine("worker thread: terminating gracefully.");
        }
        public void RequestStop()
        {
            _shouldStop = true;
        }
        // Volatile 用于向编译器提示此数据
        // 成员将由多个线程访问。
        private volatile bool _shouldStop;
    }
    
    public class WorkerThreadExample
    {
        static void Main()
        {
            // 创建线程对象。这不会启动该线程。
            Worker workerObject = new Worker();
            Thread workerThread = new Thread(workerObject.DoWork);
    
            // 启动辅助线程。
            workerThread.Start();
            Console.WriteLine("main thread: Starting worker thread...");
    
            // 循环直至辅助线程激活。
            while (!workerThread.IsAlive);
    
            // 为主线程设置 1 毫秒的休眠,
            // 以使辅助线程完成某项工作。
            Thread.Sleep(1);
    
            // 请求辅助线程自行停止:
            workerObject.RequestStop();
    
            // 使用 Join 方法阻塞当前线程, 
            // 直至对象的线程终止。
            workerThread.Join();
            Console.WriteLine("main thread: Worker thread has terminated.");
        }
    }
    View Code

    1.B.2,

    1.B.EXE,

    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: terminating gracefully.
    main thread: Worker thread has terminated.
    请按任意键继续. . .

    1.B

    1.B,ThreadPool 示例代码2(Sample Code)返回顶部

    1.B.1, ThreadPool.cs

    // 版权所有(C) Microsoft Corporation。保留所有权利。
    // 此代码的发布遵从
    // Microsoft 公共许可(MS-PL,http://opensource.org/licenses/ms-pl.html)的条款。
    //
    //版权所有(C) Microsoft Corporation。保留所有权利。
    
    using System;
    using System.Threading;
    
    // Fibonacci 类为使用辅助
    // 线程执行长时间的 Fibonacci(N) 计算提供了一个接口。
    // N 是为 Fibonacci 构造函数提供的,此外还提供了
    // 操作完成时对象发出的事件信号。
    // 然后,可以使用 FibOfN 属性来检索结果。
    public class Fibonacci
    {
        public Fibonacci(int n, ManualResetEvent doneEvent)
        {
            _n = n;
            _doneEvent = doneEvent;
        }
    
        // 供线程池使用的包装方法。
        public void ThreadPoolCallback(Object threadContext)
        {
            int threadIndex = (int)threadContext;
            Console.WriteLine("thread {0} started...", threadIndex);
            _fibOfN = Calculate(_n);
            Console.WriteLine("thread {0} result calculated...", threadIndex);
            _doneEvent.Set();
        }
    
        // 计算第 N 个斐波纳契数的递归方法。
        public int Calculate(int n)
        {
            if (n <= 1)
            {
                return n;
            }
            else
            {
                return Calculate(n - 1) + Calculate(n - 2);
            }
        }
    
        public int N { get { return _n; } }
        private int _n;
    
        public int FibOfN { get { return _fibOfN; } }
        private int _fibOfN;
    
        ManualResetEvent _doneEvent;
    }
    
    public class ThreadPoolExample
    {
        static void Main()
        {
            const int FibonacciCalculations = 10;
    
            // 每个 Fibonacci 对象使用一个事件
            ManualResetEvent[] doneEvents = new ManualResetEvent[FibonacciCalculations];
            Fibonacci[] fibArray = new Fibonacci[FibonacciCalculations];
            Random r = new Random();
    
            // 使用 ThreadPool 配置和启动线程:
            Console.WriteLine("launching {0} tasks...", FibonacciCalculations);
            for (int i = 0; i < FibonacciCalculations; i++)
            {
                doneEvents[i] = new ManualResetEvent(false);
                Fibonacci f = new Fibonacci(r.Next(20,40), doneEvents[i]);
                fibArray[i] = f;
                ThreadPool.QueueUserWorkItem(f.ThreadPoolCallback, i);
            }
    
            // 等待池中的所有线程执行计算...
            WaitHandle.WaitAll(doneEvents);
            Console.WriteLine("Calculations complete.");
    
            // 显示结果...
            for (int i= 0; i<FibonacciCalculations; i++)
            {
                Fibonacci f = fibArray[i];
                Console.WriteLine("Fibonacci({0}) = {1}", f.N, f.FibOfN);
            }
        }
    }
    View Code

    1.B.2,

    1.B.EXE,

    launching 10 tasks...
    thread 0 started...
    thread 1 started...
    thread 1 result calculated...
    thread 2 started...
    thread 2 result calculated...
    thread 3 started...
    thread 0 result calculated...
    thread 4 started...
    thread 4 result calculated...
    thread 5 started...
    thread 5 result calculated...
    thread 6 started...
    thread 6 result calculated...
    thread 7 started...
    thread 7 result calculated...
    thread 8 started...
    thread 8 result calculated...
    thread 9 started...
    thread 3 result calculated...
    thread 9 result calculated...
    Calculations complete.
    Fibonacci(27) = 196418
    Fibonacci(23) = 28657
    Fibonacci(21) = 10946
    Fibonacci(38) = 39088169
    Fibonacci(25) = 75025
    Fibonacci(25) = 75025
    Fibonacci(37) = 24157817
    Fibonacci(27) = 196418
    Fibonacci(29) = 514229
    Fibonacci(37) = 24157817
    请按任意键继续. . .
    View Code

    1.B,

    1.B,ThreadSync 示例代码3(Sample Code)返回顶部

    1.B.1, ThreadSync.cs

    // 版权所有(C) Microsoft Corporation。保留所有权利。
    // 此代码的发布遵从
    // Microsoft 公共许可(MS-PL,http://opensource.org/licenses/ms-pl.html)的条款。
    //
    //版权所有(C) Microsoft Corporation。保留所有权利。
    
    using System;
    using System.Threading;
    using System.Collections;
    using System.Collections.Generic;
    
    // 将线程同步事件封装在此类中, 
    // 以便于将这些事件传递给 Consumer 和
    // Producer 类。
    public class SyncEvents
    {
        public SyncEvents()
        {
            // AutoResetEvent 用于“新项”事件,因为
            // 我们希望每当使用者线程响应此事件时,
            // 此事件就会自动重置。
            _newItemEvent = new AutoResetEvent(false);
    
            // ManualResetEvent 用于“退出”事件,因为
            // 我们希望发出此事件的信号时有多个线程响应。
            // 如果使用 AutoResetEvent,事件
            // 对象将在单个线程作出响应之后恢复为 
            // 未发信号的状态,而其他线程将
            // 无法终止。
            _exitThreadEvent = new ManualResetEvent(false);
    
            // 这两个事件也放在一个 WaitHandle 数组中,以便
            // 使用者线程可以使用 WaitAny 方法
            // 阻塞这两个事件。
            _eventArray = new WaitHandle[2];
            _eventArray[0] = _newItemEvent;
            _eventArray[1] = _exitThreadEvent;
        }
    
        // 公共属性允许对事件进行安全访问。
        public EventWaitHandle ExitThreadEvent
        {
            get { return _exitThreadEvent; }
        }
        public EventWaitHandle NewItemEvent
        {
            get { return _newItemEvent; }
        }
        public WaitHandle[] EventArray
        {
            get { return _eventArray; }
        }
    
        private EventWaitHandle _newItemEvent;
        private EventWaitHandle _exitThreadEvent;
        private WaitHandle[] _eventArray;
    }
    
    // Producer 类(使用一个辅助线程)
    // 将项异步添加到队列中,共添加 20 个项。
    public class Producer 
    {
        public Producer(Queue<int> q, SyncEvents e)
        {
            _queue = q;
            _syncEvents = e;
        }
        public void ThreadRun()
        {
            int count = 0;
            Random r = new Random();
            while (!_syncEvents.ExitThreadEvent.WaitOne(0, false))
            {
                lock (((ICollection)_queue).SyncRoot)
                {
                    while (_queue.Count < 20)
                    {
                        _queue.Enqueue(r.Next(0, 100));
                        _syncEvents.NewItemEvent.Set();
                        count++;
                    }
                }
            }
            Console.WriteLine("Producer thread: produced {0} items", count);
        }
        private Queue<int> _queue;
        private SyncEvents _syncEvents;
    }
    
    // Consumer 类通过自己的辅助线程使用队列
    // 中的项。Producer 类使用 NewItemEvent 
    // 将新项通知 Consumer 类。
    public class Consumer
    {
        public Consumer(Queue<int> q, SyncEvents e)
        {
            _queue = q;
            _syncEvents = e;
        }
        public void ThreadRun()
        {
            int count = 0;
            while (WaitHandle.WaitAny(_syncEvents.EventArray) != 1)
            {
                lock (((ICollection)_queue).SyncRoot)
                {
                    int item = _queue.Dequeue();
                }
                count++;
            }
            Console.WriteLine("Consumer Thread: consumed {0} items", count);
        }
        private Queue<int> _queue;
        private SyncEvents _syncEvents;
    }
    
    public class ThreadSyncSample
    {
        private static void ShowQueueContents(Queue<int> q)
        {
            // 对集合进行枚举本来就不是线程安全的,
            // 因此在整个枚举过程中锁定集合以防止
            // 使用者和制造者线程修改内容
            // 是绝对必要的。(此方法仅由
            // 主线程调用。)
            lock (((ICollection)q).SyncRoot)
            {
                foreach (int i in q)
                {
                    Console.Write("{0} ", i);
                }
            }
            Console.WriteLine();
        }
    
        static void Main()
        {
            // 配置结构,该结构包含线程同步
            // 所需的事件信息。
            SyncEvents syncEvents = new SyncEvents();
    
            // 泛型队列集合用于存储要制造和使用的
            // 项。此例中使用的是“int”。
            Queue<int> queue = new Queue<int>();
    
            // 创建对象,一个用于制造项,一个用于
            // 使用项。将队列和线程同步事件传递给
            // 这两个对象。
            Console.WriteLine("Configuring worker threads...");
            Producer producer = new Producer(queue, syncEvents);
            Consumer consumer = new Consumer(queue, syncEvents);
    
            // 为制造者对象和使用者对象创建线程
            // 对象。此步骤并不创建或启动
            // 实际线程。
            Thread producerThread = new Thread(producer.ThreadRun);
            Thread consumerThread = new Thread(consumer.ThreadRun);
    
            // 创建和启动两个线程。
            Console.WriteLine("Launching producer and consumer threads...");        
            producerThread.Start();
            consumerThread.Start();
    
            // 为制造者线程和使用者线程设置 10 秒的运行时间。
            // 使用主线程(执行此方法的线程)
            // 每隔 2.5 秒显示一次队列内容。
            for (int i = 0; i < 4; i++)
            {
                Thread.Sleep(2500);
                ShowQueueContents(queue);
            }
    
            // 向使用者线程和制造者线程发出终止信号。
            // 这两个线程都会响应,由于 ExitThreadEvent 是
            // 手动重置的事件,因此除非显式重置,否则将保持“设置”。
            Console.WriteLine("Signaling threads to terminate...");
            syncEvents.ExitThreadEvent.Set();
    
            // 使用 Join 阻塞主线程,首先阻塞到制造者线程
            // 终止,然后阻塞到使用者线程终止。
            Console.WriteLine("main thread waiting for threads to finish...");
            producerThread.Join();
            consumerThread.Join();
        }
    }
    View Code

    1.B.2,

    1.B.EXE,

    Configuring worker threads...
    Launching producer and consumer threads...
    87 65 95 1 77 97 21 64 77 43 50 63 4 99 84 29 5 26 35
    41 15 71 91 26 56 21 21 18 51 15 9 25 50 5 65 82 76 99
    99 23 41 24 6 80 37 95 87 52 83 96 86 67 34 47 10 42 44 17
    40 10 44 38 75 35 85 85 92 33 25 33 86 48 12 99 7 92 36 17
    Signaling threads to terminate...
    main thread waiting for threads to finish...
    Producer thread: produced 2015587 items
    Consumer Thread: consumed 2015568 items
    请按任意键继续. . .

    1.B,

    1.C,下载地址(Free Download)返回顶部
    warn 作者:ylbtech
    出处:http://ylbtech.cnblogs.com/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    Asp.Net页面导入和导出到EXCEL
    ASP.NET打包安装的制作方法
    asp.net生成高质量缩略图通用函数(c#代码),支持多种生成方式
    aspx页面Repeater嵌套Repeater
    JAVASCRIPT校验大全
    SQL语句导入导出大全
    从DataView中生成Excel报表的方案
    用ajax实现dropdownlist多级联动实例
    ASP.NET结合存储过程写的通用搜索分页程序
    C#程序调用外部程序
  • 原文地址:https://www.cnblogs.com/ylbtech/p/4197385.html
Copyright © 2011-2022 走看看