首页 > 技术文章 > 《C#高级编程第七版》多线程之Events

theluther 2014-09-03 00:12 原文

主要是线程等待相关的基础知识,按照范例,将代码稍加变动,打出来了,当是自己学习笔记了。代码如下所示

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Text;

namespace Demo2
{
    class Program
    {
        static void Main(string[] args)
        {
            const int taskcount = 10;

            //事件数组,记录线程执行状态
            var mevents = new ManualResetEventSlim[taskcount];

            //等待数组,接收事件发出的信号
            var waithandles = new WaitHandle[taskcount];

            //执行具体任务的类
            var calcs = new Calculator[taskcount];

            //任务工厂
            TaskFactory tf = new TaskFactory();


            for (int i = 0; i < taskcount; i++)
            {
                //初始化事件
                mevents[i] = new ManualResetEventSlim(false);

                //将事件与等待绑定
                waithandles[i] = mevents[i].WaitHandle;

                //初始化执行具体任务的类
                calcs[i] = new Calculator(mevents[i]);

                //开始一个任务
                tf.StartNew(calcs[i].Calculation, Tuple.Create(i + 1, i + 3));
            }

            //Thread.Sleep(5000);
            Console.Write("task is running\r\n");

            for (int i = 0; i < taskcount; i++)
            {
                //返回执行完操作的等待数组的索引,根据索引得到具体事件,然后由该事件发出Reset信号
                int index = WaitHandle.WaitAny(waithandles);
                if (index == WaitHandle.WaitTimeout)
                {
                    Console.Write("timeout\r\n");
                }
                else
                {
                    mevents[index].Reset();
                    Console.Write("finished task for {0}\r\n", calcs[index].TaskID);
                }
            }
            Console.ReadKey(true);
        }
    }
    public class Calculator
    {
        //记录事件状态
        private ManualResetEventSlim mevent;
        public int? TaskID { get; private set; }

        public Calculator(ManualResetEventSlim ev)
        {
            this.mevent = ev;
        }

        public void Calculation(object obj)
        {
            Tuple<int, int> data = (Tuple<int, int>)obj;
            Console.Write("Task {0} starts calculation\r\n", Task.CurrentId);
            Thread.Sleep(new Random().Next(3000));
            TaskID = Task.CurrentId;
            Console.Write("Task {0} is ready\r\n", Task.CurrentId);
            mevent.Set();
        }
    }
}

  

mevents[index].Reset(); 
将这句屏蔽后,"finished task for"经常是一个固定值,不太理解为什么是这样。
不知道是不是Reset之后,waithandle就失效了,WaitHandle.WaitAny(waithandles)就不会获取重复的记录

推荐阅读