C# 代码示例详尽剖析异步调用(转)
来源:互联网 发布:帝国cms 有论坛功能吗 编辑:程序博客网 时间:2024/06/05 05:12
我上次写创建线程的时候就想写一篇深入异步调用的笔记,但是由于当时对windows的进程与线程的概念不太清楚,没敢写,今天我仔细的分析并调试了一下C#中的异步调用的四种方法。把学习笔记分享出来。
假如要在一个线程中异步执行一个方法,则先创建一个该方法的委托类型,然后CLR会自动为该委托类型定义一个BeginInvoke方法和EndInvoke方法,我们就靠这两个方法异步调用委托类型指向的方法(这句话有点绕口,呵呵)
BeginInvoke这个方法用于启动异步调用,该方法具有和要异步执行的方法具有相同的参数列表,只不过又多加了两个参数,多加的那两个参数的作用在后面介绍。执行BeginInvoke方法后,将立即返回一个IAsyncResult,用于监视被调用方法执行的进度。
EndInvoke这个方法用于得到异步调用的结果,调用BeginInvoke方法后随时可以调用EndInvoke方法,假如异步调用还没有完成,EndInvoke会阻塞到异步调用执行完毕,EndInvoke的参数包括被调用方法的out和ref参数,还有在调用BeginInvoke方法时得到的那个IAsyncResult(好像就是一个哈希表的key,可以靠这个key去得到相应的线程,这样就可以处理多线程而不至于混乱了)
第一种方法:使用BeginInvoke方法后,主线程去执行一些操作,然后再使用EndInvoke方法等待被调用方法完成,以下是示例代码
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace sample
{
class AsyncDemo // 我定义了一个演示的类,里面有一个测试方法TestMethod 其实完全可以把这个TestMethod写到Main()函数的同一个类中,只不过写成static方法即可
{
public string TestMethod(int callDuration, out int threadid)
{
Console.WriteLine("Test Method begins");
Thread.Sleep(callDuration);//睡眠callDuration指定的毫秒
threadid = AppDomain.GetCurrentThreadId();//获取当前线程的id
return "MyCallTime was" + callDuration.ToString();//返回当前线程睡眠的时间
}
}
public delegate string AsyncDelegate(int callDuration, out int threadid); //创建一个AsyncDemo类中TestMethod方法相同签名的委托类型
class Program
{
static void Main(string[] args)
{
int threadID;
AsyncDemo ad = new AsyncDemo();//声明一个AsyncDemo类型的对象ad,并创建一个实例赋给它
AsyncDelegate andl = new AsyncDelegate(ad.TestMethod);//声明一个AsyncDelegate类型的对象andl,并让他指向ad对象的TestMethod方法
IAsyncResult ar = andl.BeginInvoke(3000, out threadID, null, null);//执行andl的BeginInvoke方法,返回一个IAsyncResult类型的实例对象给ar变量,其实是一个号码牌(不知道这样说是否形象)
Thread.Sleep(10);//使当前线程睡眠10毫秒(其实可去掉这句,我写这个的目的是确保异步线程已启动,再执行以下语句)
Console.WriteLine("Main Thread {0} Does Some Work",
AppDomain.GetCurrentThreadId());//输出当前线程的id
string ret = andl.EndInvoke(out threadID, ar);//使用EndInvoke方法,传入out或ref类型参数和在调用BeginInvoke方法时得到的IAsyncResult,此时主线程将等待异步调用执行完毕,返回结果后执行以下语句
Console.WriteLine("The call executed on thread {0},with return value : {1}",
threadID, ret);
Console.ReadLine();
}
}
}
ok,以上是第一种直接使用EndInvoke来等待异步调用完成的方法
================================================
================================================
第二种方法是借助返回的IAsyncHandle的WaitHandle属性的WaitOne()方法实现线程同步后,执行代码,然后将要执行的代码执行后随时可调用EndInvoke方法。
示例代码基本没有什么改动,只是在BeginInvoke方法后执行一个ar.WaitHandle.WaitOne()方法,该方法将阻塞主线程使主线程等待返回ar的begininvoke调用的方法的线程执行完毕(不要怪我说话有点绕,我是说的详细,否则你弄不明白,仔细看这句话就明白了^o^)。
本着一切代码都是纸老虎的原则,请仔细分析下面的代码 其实和示例1基本无异 ,只是使用WaitOne()方法同步了一下线程而已
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace sample
{
class AsyncDemo
{
public string TestMethod(int callDuration, out int threadid)
{
Console.WriteLine("Test Method begins");
Thread.Sleep(callDuration);
threadid = AppDomain.GetCurrentThreadId();
return "MyCallTime was" + callDuration.ToString();
}
}
public delegate string AsyncDelegate(int callDuration, out int threadid);
class Program
{
static void Main(string[] args)
{
int threadID;
AsyncDemo ad = new AsyncDemo();
AsyncDelegate andl = new AsyncDelegate(ad.TestMethod);
IAsyncResult ar = andl.BeginInvoke(3000, out threadID, null, null);
Thread.Sleep(10);
Console.WriteLine("Main Thread {0} Does Some Work",
AppDomain.GetCurrentThreadId());
ar.AsyncWaitHandle.WaitOne();//执行该方法时主线程将等待辅助线程执行完毕,使两线程同步后再执行以下语句
Console.WriteLine("其实很简单");//执行一些方法
string ret = andl.EndInvoke(out threadID, ar);//使用EndInvoke来获取返回结果和传入ref和out的变量获取修改后的实例的位置(这我就不太好用语言来表述了,你自己心领神会吧)
Console.WriteLine("The call executed on thread {0},with return value : {1}",
threadID, ret);
Console.ReadLine();
}
}
}
假如要在一个线程中异步执行一个方法,则先创建一个该方法的委托类型,然后CLR会自动为该委托类型定义一个BeginInvoke方法和EndInvoke方法,我们就靠这两个方法异步调用委托类型指向的方法(这句话有点绕口,呵呵)
BeginInvoke这个方法用于启动异步调用,该方法具有和要异步执行的方法具有相同的参数列表,只不过又多加了两个参数,多加的那两个参数的作用在后面介绍。执行BeginInvoke方法后,将立即返回一个IAsyncResult,用于监视被调用方法执行的进度。
EndInvoke这个方法用于得到异步调用的结果,调用BeginInvoke方法后随时可以调用EndInvoke方法,假如异步调用还没有完成,EndInvoke会阻塞到异步调用执行完毕,EndInvoke的参数包括被调用方法的out和ref参数,还有在调用BeginInvoke方法时得到的那个IAsyncResult(好像就是一个哈希表的key,可以靠这个key去得到相应的线程,这样就可以处理多线程而不至于混乱了)
第一种方法:使用BeginInvoke方法后,主线程去执行一些操作,然后再使用EndInvoke方法等待被调用方法完成,以下是示例代码
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace sample
{
class AsyncDemo // 我定义了一个演示的类,里面有一个测试方法TestMethod 其实完全可以把这个TestMethod写到Main()函数的同一个类中,只不过写成static方法即可
{
public string TestMethod(int callDuration, out int threadid)
{
Console.WriteLine("Test Method begins");
Thread.Sleep(callDuration);//睡眠callDuration指定的毫秒
threadid = AppDomain.GetCurrentThreadId();//获取当前线程的id
return "MyCallTime was" + callDuration.ToString();//返回当前线程睡眠的时间
}
}
public delegate string AsyncDelegate(int callDuration, out int threadid); //创建一个AsyncDemo类中TestMethod方法相同签名的委托类型
class Program
{
static void Main(string[] args)
{
int threadID;
AsyncDemo ad = new AsyncDemo();//声明一个AsyncDemo类型的对象ad,并创建一个实例赋给它
AsyncDelegate andl = new AsyncDelegate(ad.TestMethod);//声明一个AsyncDelegate类型的对象andl,并让他指向ad对象的TestMethod方法
IAsyncResult ar = andl.BeginInvoke(3000, out threadID, null, null);//执行andl的BeginInvoke方法,返回一个IAsyncResult类型的实例对象给ar变量,其实是一个号码牌(不知道这样说是否形象)
Thread.Sleep(10);//使当前线程睡眠10毫秒(其实可去掉这句,我写这个的目的是确保异步线程已启动,再执行以下语句)
Console.WriteLine("Main Thread {0} Does Some Work",
AppDomain.GetCurrentThreadId());//输出当前线程的id
string ret = andl.EndInvoke(out threadID, ar);//使用EndInvoke方法,传入out或ref类型参数和在调用BeginInvoke方法时得到的IAsyncResult,此时主线程将等待异步调用执行完毕,返回结果后执行以下语句
Console.WriteLine("The call executed on thread {0},with return value : {1}",
threadID, ret);
Console.ReadLine();
}
}
}
ok,以上是第一种直接使用EndInvoke来等待异步调用完成的方法
================================================
================================================
第二种方法是借助返回的IAsyncHandle的WaitHandle属性的WaitOne()方法实现线程同步后,执行代码,然后将要执行的代码执行后随时可调用EndInvoke方法。
示例代码基本没有什么改动,只是在BeginInvoke方法后执行一个ar.WaitHandle.WaitOne()方法,该方法将阻塞主线程使主线程等待返回ar的begininvoke调用的方法的线程执行完毕(不要怪我说话有点绕,我是说的详细,否则你弄不明白,仔细看这句话就明白了^o^)。
本着一切代码都是纸老虎的原则,请仔细分析下面的代码 其实和示例1基本无异 ,只是使用WaitOne()方法同步了一下线程而已
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace sample
{
class AsyncDemo
{
public string TestMethod(int callDuration, out int threadid)
{
Console.WriteLine("Test Method begins");
Thread.Sleep(callDuration);
threadid = AppDomain.GetCurrentThreadId();
return "MyCallTime was" + callDuration.ToString();
}
}
public delegate string AsyncDelegate(int callDuration, out int threadid);
class Program
{
static void Main(string[] args)
{
int threadID;
AsyncDemo ad = new AsyncDemo();
AsyncDelegate andl = new AsyncDelegate(ad.TestMethod);
IAsyncResult ar = andl.BeginInvoke(3000, out threadID, null, null);
Thread.Sleep(10);
Console.WriteLine("Main Thread {0} Does Some Work",
AppDomain.GetCurrentThreadId());
ar.AsyncWaitHandle.WaitOne();//执行该方法时主线程将等待辅助线程执行完毕,使两线程同步后再执行以下语句
Console.WriteLine("其实很简单");//执行一些方法
string ret = andl.EndInvoke(out threadID, ar);//使用EndInvoke来获取返回结果和传入ref和out的变量获取修改后的实例的位置(这我就不太好用语言来表述了,你自己心领神会吧)
Console.WriteLine("The call executed on thread {0},with return value : {1}",
threadID, ret);
Console.ReadLine();
}
}
}
- C# 代码示例详尽剖析异步调用(转)
- C# 代码示例详尽剖析异步调用的两种方法
- c#委托的异步调用 简单示例
- C# 委托的三种调用示例(同步调用 异步调用 异步回调)
- C调用Python函数相关代码示例剖析
- C调用Python函数相关代码示例剖析
- 如何对远程对象进行异步调用(示例代码)
- C#版异步TCP聊天服务器端简单代码示例
- C#调用FFMPEG,并异步读取输出信息的代码
- C#委托的异步调用[转]
- C#异步调用
- C#异步方法调用
- C# 异步调用
- C# 异步调用
- C#的异步调用
- C#的异步调用
- C#异步方法调用
- C#异步调用
- 软件架构模式的种类
- GIS应用随笔
- CSDN博客放google广告
- 如果将 lotus 邮件(包括plain text,html,richtext)转化成eml文件
- 用C语言和VC6.0做个最简单的CGI程序,并且运行在apache服务器环境中。
- C# 代码示例详尽剖析异步调用(转)
- 一个网络工程给年轻工程师的忠告
- VS.NET开发小技巧——C/S程序中MDI子窗体控制其父窗体控件
- 关于Buildd
- php 代码生成工具
- 图片变化代码
- 中国通胀真相:美国向全球转嫁经济调整成本
- 关于“正在中止线程。”
- 如何解决 Visual Studio 2008 compiler could not be created 的错误