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

 更新时间:2022年05月11日 11:31:16   作者:springsnow  
这篇文章介绍了C#中异步和多线程的区别,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

一、区别和联系

异步和多线程有什么区别?其实,异步是目的,而多线程是实现这个目的的方法。异步是说,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 来“自动”生成的异步调用是使用了另外的线程(而且是线程池线程)。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • C# ThreadPool之QueueUserWorkItem使用案例详解

    C# ThreadPool之QueueUserWorkItem使用案例详解

    这篇文章主要介绍了C# ThreadPool之QueueUserWorkItem使用案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • C#中使用IFormattable实现自定义格式化字符串输出示例

    C#中使用IFormattable实现自定义格式化字符串输出示例

    这篇文章主要介绍了C#中使用IFormattable实现自定义格式字符串输出示例,本文直接给出实例代码,需要的朋友可以参考下
    2015-06-06
  • C#实现简易计算器

    C#实现简易计算器

    这篇文章主要为大家详细介绍了C#实现简易计算器,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-01-01
  • C# 指针内存控制Marshal内存数据存储原理分析

    C# 指针内存控制Marshal内存数据存储原理分析

    这篇文章主要介绍了C# 指针 内存控制 Marshal 内存数据存储原理分析,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • C#集合之并发集合的用法

    C#集合之并发集合的用法

    这篇文章介绍了C#集合之并发集合的用法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-04-04
  • C# 压榨cpu的办法(推荐)

    C# 压榨cpu的办法(推荐)

    这篇文章主要介绍了C# 压榨cpu的办法,通过修改num的值,观察cpu的核数,例如我电脑是8核的,改成8,运行时各个核都能跑满,感兴趣的朋友跟随小编一起看看吧
    2021-12-12
  • c#递归生成XML实例

    c#递归生成XML实例

    这篇文章主要介绍了c#递归生成XML的方法,以实例形式较为详细的介绍了C#的递归算法与XML操作技巧,非常具有实用价值,需要的朋友可以参考下
    2014-11-11
  • C# 实现颜色的梯度渐变案例

    C# 实现颜色的梯度渐变案例

    这篇文章主要介绍了C# 实现颜色的梯度渐变案例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • C# winfrom异步加载数据不影响窗体UI的操作方法

    C# winfrom异步加载数据不影响窗体UI的操作方法

    这篇文章主要介绍了C# winfrom 异步加载数据不影响窗体UI,在 WinForms 应用程序中,如果数据加载是一个比较耗时的操作,直接在主线程中进行加载会导致 UI 冻结,这是因为 WinForms 的 UI 是单线程的,主线程被阻塞时就无法处理其他 UI 相关的任务
    2024-12-12
  • C# 向Word中设置/更改文本方向的方法(两种)

    C# 向Word中设置/更改文本方向的方法(两种)

    在一般情况下word中输入的文字都是横向的,今天小编给大家带来两种方法来设置更改文本方向的方法,非常不错,对c# word 更改文本方向的知识感兴趣的朋友一起看看吧
    2016-08-08

最新评论