事件委托的联系

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

namespace ConsoleApp1
{
public class EventTest
{
private int value;
public delegate void NumManipulationHandler();

    public event NumManipulationHandler ChangeNum;
    protected virtual void OnNumChanged() 
    {
        if (ChangeNum != null)
        {
            ChangeNum();//事件被触发
        }
        else
        {
            Console.WriteLine("event not fire");
            Console.ReadKey();//回车继续
        }
    }
    public EventTest() 
    {
        int n = 5;
        SetValue(n);
    }

    public void SetValue(int n)
    {
        if (value != n)
        {
            value = n;
            OnNumChanged();
        }
    }
}
public class subscribEvent 
{
    public void printf() 
    {
        Console.WriteLine("event fire");
        Console.ReadKey();//回车继续
    }
}

public class MainClass 
{
    public static void Main1() 
    {
        //EventTest e = new EventTest();//实例化对象,第一次没有触发事件
        //subscribEvent v = new subscribEvent();//实例化对象
        //e.ChangeNum += new EventTest.NumManipulationHandler(v.printf);//注册
        //e.SetValue(7);
        //e.SetValue(11);
        //System.Threading.Thread t = new System.Threading.Thread(PrintNumbersWithDelay);
        //t.Start();
        //t.Join();
        //PrintNumbers();
        /*
         在C#中,对于不需要考虑严格时序的任务,线程是一个很方便的东西
        将没一个单独需要执行的事情都作为一个线程,在主函数中调用就可以了
        新建一个项目之后,需要引入线程相关的命名空间,里面包含了线程相关的class的定义功能函数等内容
        using System.Threading
        先定义一个thread类型的变量,其中th是该线程的名字,如果需要对该线程进行操作,就是对变量th的操作
        ThreadMethod则是该线程所执行的函数
        Thread th = new Thread(ThreadMethod);//创建线程
        线程函数内容如下,该函数是每隔500ms像控制台打印一次东西
        一般用到线程的情况都是一个线程一致监听并处理一些事情,所以会有一个while(true),即永不退出
        由于线程和主进程是一样,是一直在执行并且常驻内存的(一般的子函数都是在堆栈中运行,调用的时候就在堆栈中临时租借
        一块地,函数执行完了再把那块地还给你,而static关键字就是说,系统啊你要给我在内存里专门开一块地放置我的代码块
        我以后就是你的固定客户)所以线程函数也和主函数一样,需要加static关键字,并且是void类型的
        当线程需要启动时(假设你这个线程是统计景区人流量的,作为主管的你在家睡大叫,然后请一个零时工来干活)
        th.Start()//启动
        当线程需要挂其实现在你亲戚来了你给她开个后门直接放进去,这个时候暂时不需要统计了,执行Suspend函数可以实现线程的挂起
        th.Suspend
        当线程需要继续开始时(亲戚都进去完了)执行Resume函数可以实现线程的继续执行
        th.Resume();继续线程
        当线程需要停止时(下班了)执行Absort函数可以实现线程的终止
        th.Absort();//终止线程
         */
        //在Main方法下面加入以下代码片段
        Console.WriteLine("main start\r\n");
        Thread th = new Thread(ThreadMethod);//创建线程
        th.Start();//启动线程
        for (int i = 0; i < 10; i++)
        {
            if (i==3) th.Suspend();
            if (i==5) th.Resume();
            if (i==7) th.Abort();
            Console.WriteLine(i+"\r\n");
            Thread.Sleep(1000);
        }
        Console.WriteLine("main end\r\n");
        Console.ReadKey();
   
    }
    static void ThreadMethod() 
    {
        while (true)
        {
            Console.WriteLine("thread\r\n");
            Thread.Sleep(500);
        }
    }

   

    static void PrintNumbers() 
    {
        Console.WriteLine("Starting...");
        for (int i = 0; i < 10; i++)
        {
            Console.WriteLine(i);
        }
    }
    static void PrintNumbersWithDelay()
    {
        Console.WriteLine("Starting...");
        for (int i = 0; i < 10; i++)
        {
            System.Threading.Thread.Sleep(TimeSpan.FromSeconds(2));
            Console.WriteLine(i);
        }
        /*
         当程序运行时,会创建一个线程,该线程会执行PrintNumbersWithDelay方法中的代码
        然后会立即执行PrintNumbers方法。关键之处在于PrintNumbersWithDelay方法中加入了Thread.Sleep方法调用
        这将导致线程执行该代码时,在打印任何数字之前会等待指定的时间(本例中是2秒钟)。当线程处于休眠状态时
        它会占用尽可能少的CPU时间。结果我们会发现通常后运行的PrintNumbers方法中的代码比独立线程中的PrintNumbersWithDelay
        方法中的代码先执行
        1.4线程等待
        本节将展示如何让程序等待另一个线程中的计算完成,然后在代码中使用该线程的计算结果。使用Thread.Sleep行不通,有i那位并不知道
        执行计算需要花费的具体时间
        工作原理
        当程序运行时,启动了一个耗时较长的线程来打印数字,打印每个数字前要等待两秒
        但我们在主程序中调用了t.Join方法,该方法允许我们等待直到线程t完成。当线程t完成时
        主线程会继续运行。接组合该技术可以实现两个线程间同步执行步骤
        第一个线程会等待另一个线程完成后在继续执行,第一个线程等待时是处于阻塞状态(正如1.3节中调用
        Thread.Sleep方法一样)
        编程中的模式是指针对既定问题的具体的标准的方案。通常,编程模式是人们总结的经验的结果
        即分析常见的问题,并对这些问题提供方案
        由于并行编程已经存在很长一堆时间,有很多不同的模式来编写并行的应用程序
        设置有特殊的编程语言更加容易地编写特定并行算法。然而,这正是事情变得日益复杂的源头
        在本书中,我将提供一个七点从而帮助你能够进一步学习并行编程
        我们将回顾非常基础的但是非常有用的模式,这对于解决异步编程的很多常见的方案有帮助
        首先是关于在多线程中使用共享状态的对象。我想强调你应当尽可能地避免使用它
        我们在之前章节中已经讨论过了,当编写并行算法时共享状态是非常不好的方式,但在很多场合中
        它又是不可避免的。我们将学习如何延迟一个对象的计算直到需要时才进行计算,以及如何在不同场景中
        实现线程安全
        接下来的两节将展示如何创建一个结构化的并行数据流。我们将回顾生产者、消费者模式
        具体实例,其被成为并行管道(Parallel Pipeline)我们通过阻塞集合来实现它
        然后看看微软提供的另一个并行编程库-TPL数据流(TPL DataFlow)是多么有用
        我们将学习的最后一个模式是Map/Reduce模式。现代世界中,该名字可以指很多事情
        一些人认为map/reduce不是针对任何问题的通用方式,而是大型的分布式的集群计算的实现
        我们将找出该名称背后的含义,以及学习如何在小型的并行应用程序中使用该模式
        10.2 实现惰性求值的共享状态
        本节展示了如何编写一个具有惰性求值的线程安全的共享状态对象
        10.2.1 
         */
    }
}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值