C#中异步和多线程的区别介绍

作者:springsnow 时间:2021-08-23 07:06:49 

一、区别和联系

异步和多线程有什么区别?其实,异步是目的,而多线程是实现这个目的的方法。异步是说,A发起一个操作后(一般都是比较耗时的操作,如果不耗时的操作就没有必要异步了),可以继续自顾自的处理它自己的事儿,不用干等着这个耗时操作返回。.Net中的这种异步编程模型,就简化了多线程编程,我们甚至都不用去关心Thread类,就可以做一个异步操作出来。

异步有的时候用普通的线程,有的时候用系统的异步调用功能。有一些IO操作也是异步的,但是未必需要一个线程来运行。例如:硬件是有DMA功能的,在调用DMA传输数据的时候,CPU是不需要执行处理的,只需要发起传输和等待传输结束即可。具体到.net平台,比如Socket的BeginSend,如果是运行在Windows    2000以后的平台,在底层就会调用异步的完成端口来发送。

.Net中的异步执行其实使用的是异步委托。异步委托将要执行的方法提交到.net的线程池,由线程池中的线程来执行异步方法。

二、适用范围

  • 当需要执行I/O操作时,使用异步操作更合适。I/O操作不仅包括了直接的文件、网络的读写,还包括数据库操作、Web Service、HttpRequest以及.net Remoting等跨进程的调用。

  • 而线程的适用范围则是那种需要长时间CPU运算的场合,例如耗时较长的图形处理和算法执行。

三、异步的一个示例

大家可能都知道,使用delegate可以“自动”使一个方法可以进行异步的调用。从直觉上来说,我觉得是由编译器或者CLR使用了另外的线程来执行目标方法。到底是不是这样呢??让我们来用一段代码证明一下吧。

delegate void AsyncFoo(int i);

static void Main(string[] args)
{
   PrintCurrThreadInfo("Main()");
   for (int i = 0; i < 10; i++)
   {
       PostAsync();
   }
   Console.ReadLine();
}
///<summary>
/// 输出当前线程的信息
///</summary>
///<param name="name">方法名称</param>

static void PrintCurrThreadInfo(string name)
{
   Console.WriteLine("Thread Id of " + name + " is: " + Thread.CurrentThread.ManagedThreadId + ", current thread is "
            + (Thread.CurrentThread.IsThreadPoolThread ? "" : "not ")
            + "thread pool thread.");
}

///<summary>
/// 投递一个异步调用
///</summary>
static void PostAsync()
{
   AsyncFoo caller = new AsyncFoo(Foo);
   caller.BeginInvoke(1000, new AsyncCallback(FooCallBack), caller);
}

///<summary>
/// 测试方法,Sleep一定时间
///</summary>
///<param name="i">Sleep的时间</param>
static void Foo(int i)
{
   PrintCurrThreadInfo("Foo()");
   Thread.Sleep(i);
}

static void FooCallBack(IAsyncResult ar)
{
   PrintCurrThreadInfo("FooCallBack()");
   AsyncFoo caller = (AsyncFoo)ar.AsyncState;
   caller.EndInvoke(ar);
}

这段代码代码的输出如下:

Thread Id of Main() is: 1, current thread is not thread pool thread.
Thread Id of Foo() is: 3, current thread is thread pool thread.
Thread Id of FooCallBack() is: 3, current thread is thread pool thread.
Thread Id of Foo() is: 3, current thread is thread pool thread.
Thread Id of Foo() is: 4, current thread is thread pool thread.
Thread Id of Foo() is: 5, current thread is thread pool thread.
Thread Id of FooCallBack() is: 3, current thread is thread pool thread.
Thread Id of Foo() is: 3, current thread is thread pool thread.
Thread Id of FooCallBack() is: 4, current thread is thread pool thread.
Thread Id of Foo() is: 4, current thread is thread pool thread.
Thread Id of Foo() is: 6, current thread is thread pool thread.
Thread Id of FooCallBack() is: 5, current thread is thread pool thread.
Thread Id of Foo() is: 5, current thread is thread pool thread.
Thread Id of Foo() is: 7, current thread is thread pool thread.
Thread Id of FooCallBack() is: 3, current thread is thread pool thread.
Thread Id of Foo() is: 3, current thread is thread pool thread.
Thread Id of FooCallBack() is: 4, current thread is thread pool thread.
Thread Id of FooCallBack() is: 6, current thread is thread pool thread.
Thread Id of FooCallBack() is: 5, current thread is thread pool thread.
Thread Id of FooCallBack() is: 7, current thread is thread pool thread.
Thread Id of FooCallBack() is: 3, current thread is thread pool thread.

从输出可以看出,.net 使用 delegate 来&ldquo;自动&rdquo;生成的异步调用是使用了另外的线程(而且是线程池线程)。

来源:https://www.cnblogs.com/springsnow/p/9428818.html

标签:C#,异步,多线程,区别
0
投稿

猜你喜欢

  • Java使用Socket通信传输文件的方法示例

    2023-04-16 21:52:31
  • Android之线程池ThreadPoolExecutor的简介

    2021-06-27 02:41:25
  • Android P实现静默安装的方法示例(官方Demo)

    2022-04-05 20:06:13
  • @RequestBody的使用详解

    2023-03-08 04:17:28
  • 浅谈Java多线程实现及同步互斥通讯

    2022-11-17 17:50:53
  • Java annotation元注解原理实例解析

    2022-09-08 00:42:45
  • 利用logback 设置不同包下的日志级别

    2022-08-11 20:05:43
  • Java使用二分法进行查找和排序的示例

    2023-03-16 10:16:37
  • Android Spinner 组件的应用实例

    2022-07-12 04:50:13
  • SpringBoot实现MapperScan添加动态配置(占位符)

    2023-11-26 05:08:06
  • Android Studio 引用外部依赖时报错的解决方法

    2023-09-26 18:20:11
  • 深入解析Java并发程序中线程的同步与线程锁的使用

    2022-03-19 10:25:38
  • Java实现将PDF转为PDF/A

    2023-03-16 00:54:22
  • 本地jvm执行flink程序带web ui的操作

    2022-09-03 20:49:00
  • 详解java中产生死锁的原因及如何避免

    2022-04-22 00:36:14
  • c#编写webservice服务引用实例分享

    2023-05-11 19:28:41
  • 聊聊Java的switch为什么不支持long

    2023-08-24 17:35:14
  • 深入了解Java对象的克隆

    2021-10-29 13:59:35
  • 基于Springboot实现JWT认证的示例代码

    2023-04-01 09:46:40
  • Android用viewPager2实现UI界面翻页滚动的效果

    2023-06-08 02:46:43
  • asp之家 软件编程 m.aspxhome.com