zoukankan      html  css  js  c++  java
  • 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();
            }
    
    
        }
    }
  • 相关阅读:
    维护gcd的线段树 补发一波。。。
    BZOJ 4720: [Noip2016]换教室
    P2184 贪婪大陆 树状数组
    BZOJ 1047: [HAOI2007]理想的正方形 单调队列瞎搞
    POJ3280 Cheapest Palindrome 区间DP
    BZOJ 2288: 【POJ Challenge】生日礼物 堆&&链表
    BZOJ 4236: JOIOJI map瞎搞
    浅谈最近公共祖先(LCA)
    题解 BZOJ 1912 && luogu P3629 [APIO2010]巡逻 (树的直径)
    [笔记] 求树的直径
  • 原文地址:https://www.cnblogs.com/Mysterious/p/3429492.html
Copyright © 2011-2022 走看看