zoukankan      html  css  js  c++  java
  • 异步与多线程的区别

    当我们在遇到需要长时间执行的任务时候,比如读取一个文件,远程服务调用。这些功能都会阻塞主线程,造成主线程卡死,从而造成一种软件崩溃的假象。这样的情况下,我们都会想到使用异步多线程的技术去解决这个问题。

    我在学习NodeJs的之前,一直以为异步和多线程是同一个概念,当我接触到Node的时候,感觉自己遭到了当头棒喝,Node是单线程的,也不支持多线程,但是他的很多操作都是异步的,比如文件的读取。这让我很沮丧,也花了很长时间去理解异步和多线程的概念区别,现在记录下来我现在的想法,希望看到的朋友也能帮组我理解一下。

    异步,相对于同步,C#执行代码的顺序是从上到下,从右到左,从上往下执行的这种就称之为同步执行,异步相对于同步,就是同时执行的意思。

    如下流程图

    如上图是同步和异步的执行模式。

    什么是多线程?多线程是实现异步的一种技术。综上:异步是一种技术功能要求,多线程是实现异步的一种手段。除了使用多线程可以实现异步,异步I/O操作也能实现。硬盘,显卡这些硬件是可以不消耗CPU资源而自动与内存交换数据的,这也是实现异步的基本条件,当数据交互完成,再触发指定的回调函数,来实现异步之后的同步。所以这也是NodeJs的异步I/O操作全部是通过异步回调来实现的原因。

    在Net中可以使用委托实现异步调用的功能。

      Action test = () =>

                {

                    for (double i = 0; i < 10000; i++)

                    {

                        Thread.Sleep(1);

                    }

                    Console.WriteLine("耗时操作结束!");

                };

     

                test.BeginInvoke(null, null);

     

                Console.Write("程序执行结束!");

    BeginInvoke就可以实现异步操作

    BeginInvoke有两个参数一个是AsyncCallback,一个是object,前一个参数是一个委托,看名字就知道是一个回调函数,当异步执行完成之后,就会执行回调函数,object代表一个参数,如果回调函数需要参数则通过object传入。

    如果不想通过回调函数,同时又想等待异步执行完成,那么可以通过EndInvoke来实现

      Action test = () =>

                {

                    int result = 0;

                    for (int i = 0; i < 1000; i++)

                    {

                        result += i;

                        Thread.Sleep(5);

                    }

                };

     

                 test.BeginInvoke((state) =>

                {

                    Console.WriteLine("传入的参数是"+state.AsyncState);

                }, "Test");

    以上是带回调函数的示例

    Func<int> test = () =>

                {

                    int r = 0;

                    for (int i = 0; i < 1000; i++)

                    {

                        r += i;

                        Thread.Sleep(3);

                    }

                    return r;

                };

     

               var re= test.BeginInvoke(null,null);

     

               int result = test.EndInvoke(re);

    以上会为了获取运行结果的示例

  • 相关阅读:
    aspnetpager 详解
    删除sql数据库日志的方法
    Asp.Net 自带的分布式事务(TransactionScope)的代码块
    VS2010项目放到VS2008下的方法
    SQL Server 2005中的SSIS维护计划
    XML格式与DataTable、DataSet、DataView格式的转换
    .NET公共执行类
    C#学习BackgroundWork
    <winform>源代码
    C#学习Thread
  • 原文地址:https://www.cnblogs.com/ckym/p/11438497.html
Copyright © 2011-2022 走看看