异步编程

同步方法

程序运行的时候,在调用其他方法的时候,会等待被调用的方法按顺序执行完,才会继续执行。非常符合开发思维,有序执行(这个意思是干啥都是一起干(不管多少程序)等最慢的或者最长的完成之后才可以统一完成(铁哥们)(括号内自我理解如果不对就别当回事))
异步方法

在程序调用异步方法的时候,主程序不会等待方法执行完,而是主程序调用异步方法后直接继续运行,而异步方法会启动一个新线程来完成方法的计算。(异步相等于VIP干啥都是有特殊通道(括号内自我理解如果不对就别当回事))

异步编程

委托的异步调用

  1. 先根据比较耗时的功能方法声明对应的委托
  2. 给委托赋值,赋与这个耗时的功能函数
  3. 采用委托的BeginInvoke方法进行异步调用委托
    Invoke方法:类似于默认的方法调用,相当于直接使用()调用委托
    BeginInvoke方法:指采取异步调用委托
  4. 给BeginInvoke方法创建回调函数
    回调函数:回调函数是指,当前的正在执行的操作完成之后,立刻回调用的一个函数是回调函数
    BeginInvoke方法参数组成:
    1. 第一组参数:委托所指向的方法对应的参数
    2. AsyncCallback参数:与当前委托对应的回调函数
    3. object参数:假如回调函数需要参数则由object参数提供
      BeginInvoke方法返回值为IAsyncResult,而委托的回调函数必须有一个参数为IAsyncResult类型
  5. 通过EndInvoke获取对应委托的BeginInvoke的执行结果
  6. 因为BeginInvoke相当于重新创建的线程进行异步调用方法函数,所以回调函数也是异步的线程的执行的,那么异步线程和程序主线程相当于阳关道和独木桥,
    因此如果使用Winform或WPF中的控件要考虑清楚:UI中的控件等都是Winform或WPF主线程中创建的,而异步线程无法直接使用
    设置CheckForIllegalCrossThreadCalls =false,这个属性是用来设置Winform或者WPF中的主线程不在做控件的跨线程检测
public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private void button1_Click_1(object sender, EventArgs e)
        {
            int a = 0;
            //多线程编程
            //委托:ParameterizedThreadStart
            Thread objThread1 = new Thread(() =>
             {
                 for (int i = 0; i < 10; i++)
                 {
                     a += i;
                     //当 一个控件的InvokeRequired属性值为真时,说明有一个创建它以外的线程想访问它,此时它将会在内部调用new MethodInvoker(LoadGlobalImage)来完成下面的步骤,
                     if (label1.InvokeRequired)
                     {
                         //Invoke方法:类似于默认的方法调用,相当于直接使用()调用委托
                         label1.Invoke(new Action<string>(s =>
                         {
                             label1.Text = $"【{s}】";
                         }), a.ToString());
                     }
                     Thread.Sleep(500);
                 }
             });
            objThread1.IsBackground = true;//设置为后台线程
            objThread1.Start();//启动任务,将其调度到当前任务调度程序执行。
        }

        private void button2_Click(object sender, EventArgs e)
        {
            int a = 0;
            Thread objThread02 = new Thread(() =>
            {
                for (int i = 0; i < 100; i++)
                {
                    a += i;
                    if (label2.InvokeRequired)
                    {
                        label2.Invoke(new Action<int>(s =>
                        {
                            label2.Text = $"【{s}】";
                        }), a);
                        Thread.Sleep(200);
                    }
                }
            });
            objThread02.IsBackground = true;
            objThread02.Start();
        }
    }

异步编程总结

  1. 异步编程是建立在委托基础上的一种编程方法
  2. 异步调用的每个方法都是独立的线程执行。因此。本质上就是一种多线程程序,也可以说是一种简化版本的多线程技术
  3. 比较适合在后台运行较为耗时的简单任务,并且任务要求相互独立,任务中不应该有代码直接访问可视化控件
  4. 如果后台任务要求必须按照特定顺序执行,或者必须访问公共资源,则异步编程不适合,而直接使用多线程技术

多线程的异步

public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private void button1_Click_1(object sender, EventArgs e)
        {
            int a = 0;
            //多线程编程
            //委托:ParameterizedThreadStart
            Thread objThread1 = new Thread(() =>
             {
                 for (int i = 0; i < 10; i++)
                 {
                     a += i;
                     //当 一个控件的InvokeRequired属性值为真时,说明有一个创建它以外的线程想访问它,此时它将会在内部调用new MethodInvoker(LoadGlobalImage)来完成下面的步骤,
                     if (label1.InvokeRequired)
                     {
                         //Invoke方法:类似于默认的方法调用,相当于直接使用()调用委托
                         label1.Invoke(new Action<string>(s =>
                         {
                             label1.Text = $"【{s}】";
                         }), a.ToString());
                     }
                     Thread.Sleep(500);
                 }
             });
            objThread1.IsBackground = true;//设置为后台线程
            objThread1.Start();//启动任务,将其调度到当前任务调度程序执行。
        }

        private void button2_Click(object sender, EventArgs e)
        {
            int a = 0;
            Thread objThread02 = new Thread(() =>
            {
                for (int i = 0; i < 100; i++)
                {
                    a += i;
                    if (label2.InvokeRequired)
                    {
                        label2.Invoke(new Action<int>(s =>
                        {
                            label2.Text = $"【{s}】";
                        }), a);
                        Thread.Sleep(200);
                    }
                }
            });
            objThread02.IsBackground = true;
            objThread02.Start();
        }
    }

后台线程

指的是程序中的一些功能不需要和一般线程同时执行,或者这些功能对于UI界面中显示方面要求不高,可以设置为后台线程

例如:VS工具中的,编译检测功能就是后台线程,当VS启动起来,除过前台线程给我们展示编辑菜单等界面,同时后台运行了检测程序
句柄(Handle)

句柄是一个标识符,用于代表操作系统中的各种资源,比如各种窗体、GDI绘图对象、进程和线程对象、文件等都用句柄

句柄使用

  1. 即使进程退出,很多时候操作系统仍然保持进程句柄,操作系统句柄有限,使用用需要节省,比如打开文件后,使用完毕要及时关闭
  2. 句柄可以通过Process对象的Handle属性访问,比如进程退出的代码,时间等

总结:拥有图形界面的程序都有一个主窗体,这个窗体也对应有一个句柄。当窗体关闭时进程也关闭。主窗体一般由主线程负责创建

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值