同步方法和异步方法:

同步方法调用在程序继续执行之前需要等待同步方法执行完毕返回结果。(比如烧水泡茶,需要等水烧开了才能继续泡茶)

异步方法则在被调用之后立即返回以便程序在被调用方法完成其任务的同时执行其它操作。(比如烧水做饭,当水烧着的时候,还可以做饭)

定义一个下载的方法:

private void Download(string filename)
{
Console.WriteLine($"开始Download {filename}******当前线程:{Thread.CurrentThread.ManagedThreadId}");
Thread.Sleep(new Random().Next(, ) * );
Console.WriteLine($"Download {filename} 完成******当前线程:{Thread.CurrentThread.ManagedThreadId}");
}

使用同步方法调用:

 Console.WriteLine($"下载开始*******当前线程:{Thread.CurrentThread.ManagedThreadId}");
for (int i = ; i < ; i++)
{
string file = "文件" + i;
this.Download(file);
}
Console.WriteLine($"下载结束*******当前线程:{Thread.CurrentThread.ManagedThreadId}");

输出结果:文件按顺序下载,所有的线程ID都是1

使用异步方法调用:

Console.WriteLine($"下载开始*******当前线程:{Thread.CurrentThread.ManagedThreadId}");
Action<string> action = this.Download;
for (int i = ; i < ; i++)
{
string file = "文件" + i;
action.BeginInvoke(file, null, null);
}
Console.WriteLine($"下载结束*******当前线程:{Thread.CurrentThread.ManagedThreadId}");

输出结果:文件下载顺序不固定,结束顺序不固定,每个下载都有自己的线程ID。

BeginInvoke 方法用于启动异步调用。它与需要异步执行的方法具有相同的参数,只不过还有两个额外的参数。

BeginInvoke 立即返回,不等待异步调用完成。

EndInvoke 方法用于检索异步调用结果。调用 BeginInvoke 后可随时调用 EndInvoke 方法;如果异步调用未完成,EndInvoke 将一直阻塞到

回调方法:

是通过将线程执行后,需要继续执行传入的方法。方法可以自定义。AsyncState为BeginInvoke 传入的第三个object参数。

Console.WriteLine($"下载大文件开始*******当前线程:{Thread.CurrentThread.ManagedThreadId}");
Action<string> action = this.Download;
string file = "流浪地球.MP4";
AsyncCallback asyncCallback = ar=> {
Console.WriteLine($"{ar.AsyncState}*******当前线程:{Thread.CurrentThread.ManagedThreadId}");
}; action.BeginInvoke(file, asyncCallback, "开始播放电影"); Console.WriteLine($"下载大文件结束*******当前线程:{Thread.CurrentThread.ManagedThreadId}");

调用结果:

BeginInvoke 返回值 IasyncResult

IsComplate 属性等待,通过判断可以知道线程是否已经执行完成。

    Console.WriteLine($"下载大文件开始*******当前线程:{Thread.CurrentThread.ManagedThreadId}");
Action<string> action = this.Download;
string file = "流浪地球.MP4";
IAsyncResult asyncResult = null;
AsyncCallback asyncCallback = ar =>
{
Console.WriteLine($"{ar.AsyncState}*******当前线程:{Thread.CurrentThread.ManagedThreadId}");
}; asyncResult = action.BeginInvoke(file, asyncCallback, "开始播放电影");
int i = ;
while (!asyncResult.IsCompleted)
{
if (i <= )
{
Console.WriteLine($"下载了{i * 10}%");
}
else
{
Console.WriteLine($"下载了99.99%");
}
Thread.Sleep();
i++;
} Console.WriteLine($"下载大文件结束*******当前线程:{Thread.CurrentThread.ManagedThreadId}");

WaitOne等待,即时等待  限时等待

asyncResult.AsyncWaitHandle.WaitOne();//直接等待任务完成

asyncResult.AsyncWaitHandle.WaitOne(-1);//一直等待任务完成

asyncResult.AsyncWaitHandle.WaitOne(5000);//最多等待5000ms,超时就不等了

EndInvoke  即时等待,而且可以获取委托的返回值 一个异步操作只能End一次

int iEndResult=action.EndInvoke(asyncResult);//等待某次异步调用操作结束,获取返回值

委托的多线程方法BeginInvoke的更多相关文章

  1. C#常用多线程方法

    1.  Thread类 C#多线程编程中Thread类需要包含名称空间System.Threading. class Program { static void Main(string[] args) ...

  2. 六种多线程方法解决UI线程堵塞

    http://blog.csdn.net/oyi319/article/details/6851371 一.六种多线程方法 .NET Framework2.0框架提供了至少4种方式实现多线程,它们是& ...

  3. 委托异步调用时BeginInvoke的陷阱处理

    这个陷阱来自于一个需求:需要异步在后台处理数据,处理完后触发处理完成的事件,大概是这么写的: EmployeeCollection data = new EmployeeCollection(): d ...

  4. 用五分钟重温委托,匿名方法,Lambda,泛型委托,表达式树

    这些对老一代的程序员都是老生常谈的东西,没什么新意,对新生代的程序员却充满着魅力.曾经新生代,好多都经过漫长的学习,理解,实践才能掌握委托,表达式树这些应用.今天我尝试用简单的方法叙述一下,让大家在五 ...

  5. 转帖:用五分钟重温委托,匿名方法,Lambda,泛型委托,表达式树

    用五分钟重温委托,匿名方法,Lambda,泛型委托,表达式树 这些对老一代的程序员都是老生常谈的东西,没什么新意,对新生代的程序员却充满着魅力.曾经新生代,好多都经过漫长的学习,理解,实践才能掌握委托 ...

  6. C# 匿名委托、匿名方法、匿名对象、Lambda表达式

    一.匿名类型可通过使用 new 运算符和对象初始值创建匿名类型.示例:var v = new { Name = "Micro", Message = "Hello&quo ...

  7. C# 委托简单使用方法

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  8. 通过Func 委托理解委托和匿名方法及Lambda 表达式

    Func<T, TResult> 委托 封装一个具有一个参数并返回 TResult 参数指定的类型值的方法. 命名空间: System 程序集: mscorlib(在 mscorlib.d ...

  9. c#-委托,匿名方法,lambda表达的关系

    什么是委托: 包含单个方法的委托和函数指针是相似的,不同的是,委托是面向帝乡的并且是类型安全的 声明委托类型: delegate void mydel(int x); 声明委托和声明方法差不多,两个不 ...

随机推荐

  1. netty 之 telnet HelloWorld 详解

    前言 Netty是 一个异步事件驱动的网络应用程序框架, 用于快速开发可维护的高性能协议服务器和客户端. etty是一个NIO客户端服务器框架,可以快速轻松地开发协议服务器和客户端等网络应用程序.它极 ...

  2. MySQL 复制 - 性能与扩展性的基石 1:概述及其原理

    1. 复制概述 MySQL 内置的复制功能是构建基于 MySQL 的大规模.高性能应用的基础,复制解决的基本问题是让一台服务器的数据与其他服务器保持同步. 接下来,我们将从复制概述及原理.复制的配置. ...

  3. sau交流学习社区--在element-ui中新建FormData对象组合上传图片和文件的文件对象,同时需要携带其他参数

    今天有一个坑,同时要上传图片和文件,而且图片要展示缩略图,文件要展示列表. 我的思路是: 首先,只上传附件照片,这个直接看ele的官方例子就行,不仅仅上传附件照片,还同时上传其他参数. 然后,再做上传 ...

  4. slice是什么时候决定要扩张?

    slice是什么时候决定要扩张? 网上说slice的文章已经很多了,大都已经把slice的内存扩张原理都说清楚了.但是是如何判断slice是否需要扩张这个点却没有说的很清楚.想当然的我会觉得这个app ...

  5. MyBatis中主键回填的两种实现方式

    主键回填其实是一个非常常见的需求,特别是在数据添加的过程中,我们经常需要添加完数据之后,需要获取刚刚添加的数据 id,无论是 Jdbc 还是各种各样的数据库框架都对此提供了相关的支持,本文我就来和和大 ...

  6. FreeSql 如何实现 Sqlite 跨库查询

    FreeSql 是 .NetFramework 4.6+..NetCore 下的 ORM 功能库,提供了丰富的功能,支持五种流行数据库 MySql/SqlServer/PostgreSQL/Oracl ...

  7. Linux三剑客-grep || awk || sed

    grep是一个强大的文本搜索工具 命令格式: grep [option] pattren file -a  将二进制文档以文本方式处理 -c  计算找到的符合行的次数 -i  忽略大小写 -n  顺便 ...

  8. HTML文档编写规范

    (1)HTML标记是由尖括号包围的关键词.所有标记均以“<”开始,以“>”结束.结束的标记在开始名称前加上斜杠“/”.例如头部标记格式如下所示:<head> ……</he ...

  9. K3数据字典备查

    select distinct f.FNumber as 系统代码, f.FName AS 系统名称,  d.FTableName AS 表名,d.FDescription AS 表说明,a.[nam ...

  10. Android拦截并获取WebView内部POST请求参数

    起因: 有些时候自家APP中嵌入的H5页面并不是自家的.但是很多时候又想在H5不知情的情况下获取H5内部请求的参数,这应该怎么做到呢? 带着这个疑问,就有了这篇博客. 实现过程: 方案一: 最开始想到 ...