c# 多线程与异步调用
异步操作的本质
在方法调用前为异步方法指定一个回调函数,方法调用后被线程池中的一个线程接管,执行该方法。主线程立即返回,继续执行其他工作或响应用户请求。如果异步方法执行完 毕,回调函数被自动执行,以处理异步方法的调用结果。 如何实现异步方法呢?C#通过异步委托调用BeginInvoke和EndInvoke方法来实现异步方法。
BeginInvoke方法原型: IAsyncResult BeginInvoke(......, AsyncCallback callback, object o); ......表示异步委托中定义的参数列表。 AsyncCallback参数是一个用于 回调函数的委托,它的原型为: public delegate void AsyncCallback(IAsyncResult ar)。其中IAsyncResult参数用于包装异步方法的执行结果。 Object参数用于在主线程与回调函数间传递一些附加信息,如同步信息。
EndInvoke方法原型: xxx EndInvoke(IAsyncResult result); xxx表示异步委托原型中定义的返回数据类型,IAsyncResult用于包装异步方法的执行结果。
线程的本质
线程不是一个计算机硬件的功能,而是操作系统提供的一种逻辑功能,线程本质上是进程中一段并发运行的代码,所以线程需要操作系统投入CPU资源来运行和调度。
异步操作的优缺点
因为异步操作无须额外的线程负担,并且使用回调的方式进行处理,在设计良好的情况下,处理函数可以不必使用共享变量(即使无法完全不用,最起码可以减少共享变量的数量),减少了死锁的可能。当然异步操作也并非完美无暇。编写异步操作的复杂程度较高,程序主要使用回调方式进行处理,与普通人的思维方式有些初入,而且难以调试。
多线程的优缺点
多线程的优点很明显,线程中的处理程序依然是顺序执行,符合普通人的思维习惯,所以编程简单。但是多线程的缺点也同样明显,线程的使用(滥用)会给系统带来上下文切换的额外负担。并且线程间的共享变量可能造成死锁的出现。
适用范围
在了解了线程与异步操作各自的优缺点之后,我们可以来探讨一下线程和异步的合理用途。我认为:当需要执行I/O操作时,使用异步操作比使用线程+同步I/O操作更合适。I/O操作不仅包括了直接的文件、网络的读写,还包括数据库操作、Web Service、HttpRequest以及.Net Remoting等跨进程的调用。
而线程的适用范围则是那种需要长时间CPU运算的场合,例如耗时较长的图形处理和算法执行。但是往往由于使用线程编程的简单和符合习惯,所以很多朋友往往会使用线程来执行耗时较长的I/O操作。这样在只有少数几个并发操作的时候还无伤大雅,如果需要处理大量的并发操作时就不合适了。
下面看个异步调用的实例:
using System;
using System.Threading; namespace AsyncDelegateDemo
{
delegate void AsyncFoo(int i);
class Program
{
///<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>
/// 测试方法,Sleep一定时间
///</summary>
///<param name="i">Sleep的时间</param>
static void Foo(int i)
{
PrintCurrThreadInfo("Foo()");
Thread.Sleep(i);
} ///<summary>
/// 投递一个异步调用
///</summary>
static void PostAsync()
{
AsyncFoo caller = new AsyncFoo(Foo);
caller.BeginInvoke(, new AsyncCallback(FooCallBack), caller);
} static void Main(string[] args)
{
PrintCurrThreadInfo("Main()");
for(int i = ; i < ; i++)
{
PostAsync();
}
Console.ReadLine();
} static void FooCallBack(IAsyncResult ar)
{
PrintCurrThreadInfo("FooCallBack()");
AsyncFoo caller = (AsyncFoo) ar.AsyncState;
caller.EndInvoke(ar); }
}
}
这段代码代码的输出如下:
Thread Id of Main() is: , current thread is not thread pool thread.
Thread Id of Foo() is: , current thread is thread pool thread.
Thread Id of FooCallBack() is: , current thread is thread pool thread.
Thread Id of Foo() is: , current thread is thread pool thread.
Thread Id of Foo() is: , current thread is thread pool thread.
Thread Id of Foo() is: , current thread is thread pool thread.
Thread Id of FooCallBack() is: , current thread is thread pool thread.
Thread Id of Foo() is: , current thread is thread pool thread.
Thread Id of FooCallBack() is: , current thread is thread pool thread.
Thread Id of Foo() is: , current thread is thread pool thread.
Thread Id of Foo() is: , current thread is thread pool thread.
Thread Id of FooCallBack() is: , current thread is thread pool thread.
Thread Id of Foo() is: , current thread is thread pool thread.
Thread Id of Foo() is: , current thread is thread pool thread.
Thread Id of FooCallBack() is: , current thread is thread pool thread.
Thread Id of Foo() is: , current thread is thread pool thread.
Thread Id of FooCallBack() is: , current thread is thread pool thread.
Thread Id of FooCallBack() is: , current thread is thread pool thread.
Thread Id of FooCallBack() is: , current thread is thread pool thread.
Thread Id of FooCallBack() is: , current thread is thread pool thread.
Thread Id of FooCallBack() is: , current thread is thread pool thread.
c# 多线程与异步调用的更多相关文章
- 异步和多线程,委托异步调用,Thread,ThreadPool,Task,Parallel,CancellationTokenSource
1 进程-线程-多线程,同步和异步2 异步使用和回调3 异步参数4 异步等待5 异步返回值 5 多线程的特点:不卡主线程.速度快.无序性7 thread:线程等待,回调,前台线程/后台线程, 8 th ...
- Java多线程实现异步调用
在Java平台,实现异步调用的角色有如下三个角色:调用者. 提货单 .真实数据,一个调用者在调用耗时操作,不能立即返回数据时,先返回一个提货单 .然后在过一断时间后凭提货单来获取真正的数据.去蛋糕店买 ...
- 衔接UI线程和管理后台工作线程的类(多线程、异步调用)
一个不错的UI多线程操作类 http://www.cnblogs.com/net66/archive/2005/08/03/206132.html
- 【摘要】多线程 - BeginInvoke异步调用
private delegate int MyMethod(); private int method() { Thread.Sleep(); ; } private void MethodCompl ...
- C# 多线程详解 Part.02(UI 线程和子线程的互动、ProgressBar 的异步调用)
我们先来看一段运行时会抛出 InvalidOperationException 异常的代码段: private void btnThreadA_Click(object sender, ...
- PHP中实现异步调用多线程程序代码
本文章详细的介绍了关于PHP中实现异步调用多线程方法,下面我们以给1000个用户发送一封推荐邮件,用户输入或者导入邮件账号了提交服务器执行发送来讲述. 比如现在有一个场景,给1000个用户发送一封推荐 ...
- 多线程编程学习笔记——异步调用WCF服务
接上文 多线程编程学习笔记——使用异步IO 接上文 多线程编程学习笔记——编写一个异步的HTTP服务器和客户端 接上文 多线程编程学习笔记——异步操作数据库 本示例描述了如何创建一个WCF服务,并宿主 ...
- MacOS和iOS开发中异步调用与多线程的区别
很多童鞋可能对Apple开发中的异步调用和多线程的区别不是太清楚,这里本猫将用一些简单的示例来展示一下它们到底直观上有神马不同. 首先异步调用可以在同一个线程中,也可以在多个不同的线程中.每个线程都有 ...
- 那些年我们一起追逐的多线程(Thread、ThreadPool、委托异步调用、Task/TaskFactory、Parallerl、async和await)
一. 背景 在刚接触开发的头几年里,说实话,根本不考虑多线程的这个问题,貌似那时候脑子里也有没有多线程的这个概念,所有的业务都是一个线程来处理,不考虑性能问题,当然也没有考虑多线程操作一条记录存在的并 ...
随机推荐
- jQuery 复合选择器的几个例子
<!-- 本文例子所引用的jQuery版本为 jQuery-1.8.3.min.js Author:博客园小dee --> 一. 复合选择器对checkbox的相关操作 1 <inp ...
- 送给使用phpstorm+thinkphp开发者的福利
送给使用phpstorm+thinkphp开发者的福利 记得两年前的这个时候,我开始学习php.我选择了thinkphp入门,写了我的第一个简单的cms.当时我什么都不懂,但是这里的技术氛围好的, ...
- Unknown collation: 'utf8mb4_unicode_ci'
日前给一个政府机关做个小的门户网站,用的是wordpress+主题开发,部署时发现导入数据库sql文本时出现Unknown collation: 'utf8mb4_unicode_ci'的错误,查了下 ...
- [转]20个高级Java面试题汇总
http://saebbs.com/forum.php?mod=viewthread&tid=37567&page=1&extra= 这是一个高级Java面试系列题中的第一部分 ...
- Java中的定时调度
Timer类是一个线程设施,用于实现在某个时间或者某一段时间后安排某个任务执行一次或者定期重复执行.需要与TimerTask配合使用. TimerTask类用来实现由Timer安排的一次或重复执行的某 ...
- ServletContextDemo
1.servlet 之间共享数据 package xw.servlet; import javax.servlet.ServletContext; import javax.servlet.http. ...
- 使用微信JS-SDK 实现 自定义 分享 功能
微信PC端点击页面,转发给朋友.
- AppDelegate
一.基础知识 1) main.m指定了程序的入口点 UIApplicationMain(argc, argv,nil,NSStringFromClass([StartingPointAppDelega ...
- Scrum 的相关概念
Scrum 的相关概念 4.1 Scrum 的起源 Scrum 是一种灵活的敏捷软件开发管理过程,这个名词来源于英式橄榄球.Scrum方法由Ken Schwaber和Jeff Sutherland ...
- JDK核心包学习
StringBuffer 线程安全.可变字符序列 StringBuilder 非线程安全.可变字符序列,比StringBuffer更快 Boolean 使用valueOf产生Boolean实例 ...