C#线程通信与异步委托

线程的通知机制

AutoResetEvent是线程实现通知操作的重要方法。通常,AutoResetEvent用于通知正在等待线程已发生事件,允许线程通过发信号互相通信。

AutoResetEvent时间对象提供了给我们可以控制线程执行的先后顺序,他的常用方法:

Set设置并发送信号

Reset重置信号,也就是使信号无效

WaitOne等待一个信号

WaitAny静态方法,等待一个信号数组,信号数组里面有任何信号都可以,否则等待

WaitAll静态方法,等待一个i额信号数组,信号数组里面的信号全部到齐才可以,否则等待

 

创建一个AutoResetEvent对象,构造方法里面需要带一个bool类型的参数,

AutoResetEvent myResetEvent = new AutoResetEvent(false);

这个参数如果是false表示时间开始是无信号状态的,当参数为true表示创建的时间开始是有信号的,就相当于使用false参数创建时间后立即设定了Set方法。

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

namespace AutoResetEventTest
{
    class Program
    {
        static AutoResetEvent myResetEvent = new AutoResetEvent(false);
        static int number;
        static void Main(string[] args)
        {
            Thread t = Thread.CurrentThread;
            t.Name = "写线程";

            Thread myReaderThread = new Thread(MyReadThreadProc);
            myReaderThread.Name = "读线程";
            myReaderThread.Start();

            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine("{0}写的值是{1}", t.Name, i);
                number = i;
                myResetEvent.Set();
                Thread.Sleep(1);
            }

            myReaderThread.Abort();
        }

        static void MyReadThreadProc()
        {
            while (true)
            {
                myResetEvent.WaitOne();
                Console.WriteLine("{0}读到的值是{1}", Thread.CurrentThread.Name, number);
            }
        }
    }
}

例程2

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

namespace AutoResetEventTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Person p = new Person();
            Thread th1 = new Thread(p.GetCar);
            th1.Start();
            Thread th2 = new Thread(p.GetHome);
            th2.Start();
            Thread th3 = new Thread(p.GetWife);
            th3.Start();
            AutoResetEvent.WaitAll(p.autoEvents);

            p.ShowHappiness();
        }

     
    }

    public class Person
    {
        public AutoResetEvent[] autoEvents;
        public Person()
        {
            autoEvents = new AutoResetEvent[]
            {
                new AutoResetEvent(false),
                new AutoResetEvent(false),
                new AutoResetEvent(false)
            };
        }
        public void GetCar()
        {
            Console.WriteLine("捡到宝马");
            autoEvents[0].Set();
        }
        public void GetHome()
        {
            Console.WriteLine("赚到房子");
            autoEvents[1].Set();
        }
        public void GetWife()
        {
            Console.WriteLine("骗到老婆");
            autoEvents[2].Set();
        }
        public void ShowHappiness()
        {
            Console.WriteLine("好成功哦,好幸福!!!~~~");
        }
    }
}

 

例程3 异步回调

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

namespace AutoResetEventTest
{
    class Program
    {
        public delegate int TaskDelegate(object obj, int ms);

        public static int GouDui(object obj, int ms)
        {
            Thread t = Thread.CurrentThread;
            t.Name = "灰太狼";
            Console.WriteLine("老板给了{0}元,让伟大的{1}来勾引你,识相的话赶紧上钩", obj.ToString(), t.Name);
            Thread.Sleep(ms);
            return 3000;
        }

        static void TakesAWhileCompleted(IAsyncResult ar)
        {
            //判断IAsyncResult对象是否有效,为空则抛出异常
            if(ar == null)
            {
                throw new ArgumentNullException("ar");
            }

            //将ar对象中AsyncState属性强类型转换为TaskDelegate委托类型
            TaskDelegate d1 = ar.AsyncState as TaskDelegate;
            //跟踪检查d1是否有效,如果无效则显示提示消息
            System.Diagnostics.Trace.Assert(d1 != null,"无效的对象类型");
            //执行委托方法,并将结果交给变量result
            int result = d1.EndInvoke(ar);

            Console.WriteLine("结果泡了{0}个漂漂的mm",result);
        }

        static void Main(string[] args)
        {
            Thread t1 = Thread.CurrentThread;
            t1.Name = "单行道酒吧";

            Console.WriteLine("去{0}给我勾搭几个mm回来!超时每秒抠你100块工资", t1.Name);

            //为委托指定执行方法
            TaskDelegate t = GouDui;
            //使用魏国的BeginInvoke方法为所委托的方法赋值,并将执行结果交给IasyncResult接口
            IAsyncResult ir = t.BeginInvoke(600000, 1000 * new Random().Next(5), TakesAWhileCompleted, t);

            //Thread.Sleep(2000);

            //int i = 0;
            //while (!ir.IsCompleted)
            //{
            //    i++;
            //    Console.WriteLine(i.ToString());


            //    //方法1 
            //    //Thread.Sleep(100);
            //    //方法2
            //    if (ir.AsyncWaitHandle.WaitOne(100, false))
            //    {
            //        Console.WriteLine("怎么还不回来,再扣就把钱扣完了!");
            //        break;
            //    }
            //}

            ////获取委托方法执行后返回的值
            //int result = t.EndInvoke(ir);
            //Console.WriteLine("报告老板,我一共给你勾兑了{0}个超级mm", result.ToString());
            //if (i >= 1)
            //{
            //    Console.WriteLine("非常好,课时你耽误了{0}个小时,所以扣除你{1}块的报酬", i.ToString(), (100 * i).ToString());
            //}
            //else
            //{
            //    Console.WriteLine("小伙子不错哦。哥很欣赏你!");
            //}
            Console.ReadKey();
        }


    }
}
posted on 2013-11-18 14:54  神秘藏宝室  阅读(417)  评论(0编辑  收藏  举报

 >>>转载请注明出处<<<