[转载]C#异步调用四大方法详解
C#异步调用四大方法是什么呢?C#异步调用四大方法的使用是如何进行的呢?让我们首先了解下什么时候用到C#异步调用:
.NET Framework 允许您C#异步调用任何方法。定义与您需要调用的方法具有相同签名的委托;公共语言运行库将自动为该委托定义具有适当签名的 BeginInvoke 和 EndInvoke 方法。
BeginInvoke 方法用于启动C#异步调用。它与您需要异步执行的方法具有相同的参数,只不过还有两个额外的参数(将在稍后描述)。BeginInvoke 立即返回,不等待C#异步调用完成。BeginInvoke 返回 IasyncResult,可用于监视调用进度。
EndInvoke 方法用于检索C#异步调用结果。调用 BeginInvoke 后可随时调用 EndInvoke 方法;如果C#异步调用未完成,EndInvoke 将一直阻塞到C#异步调用完成。EndInvoke 的参数包括您需要异步执行的方法的 out 和 ref 参数(在 Visual Basic 中为 ByRef 和 ByRef)以及由 BeginInvoke 返回的 IAsyncResult。
注意 Visual Studio .NET 中的智能感知功能会显示 BeginInvoke 和 EndInvoke 的参数。如果您没有使用 Visual Studio 或类似的工具,或者您使用的是 C# 和 Visual Studio .NET,请参见异步方法签名获取有关运行库为这些方法定义的参数的描述。
本主题中的代码演示了四种使用 BeginInvoke 和 EndInvoke 进行C#异步调用的常用方法。调用了 BeginInvoke 后,可以:
· 进行某些操作,然后调用 EndInvoke 一直阻塞到调用完成。
· 使用 IAsyncResult.AsyncWaitHandle 获取 WaitHandle,使用它的 WaitOne 方法将执行一直阻塞到发出 WaitHandle 信号,然后调用 EndInvoke。
· 轮询由 BeginInvoke 返回的 IAsyncResult,确定C#异步调用何时完成,然后调用 EndInvoke。
· 将用于回调方法的委托传递给 BeginInvoke。该方法在C#异步调用完成后在 ThreadPool 线程上执行,它可以调用 EndInvoke。
警告:始终在C#异步调用完成后调用 EndInvoke。
测试方法和异步委托
四个示例全部使用同一个长期运行的测试方法 TestMethod。该方法显示一个表明它已开始处理的控制台信息,休眠几秒钟,然后结束。TestMethod 有一个 out 参数(在 Visual Basic 中为 ByRef),它演示了如何将这些参数添加到 BeginInvoke 和 EndInvoke 的签名中。您可以用类似的方式处理 ref 参数(在 Visual Basic 中为 ByRef)。
下面的代码示例显示 TestMethod 以及代表 TestMethod 的委托;若要使用任一示例,请将示例代码追加到这段代码中。
注意 为了简化这些示例,TestMethod 在独立于 Main() 的类中声明。或者,TestMethod 可以是包含 Main() 的同一类中的 static 方法(在 Visual Basic 中为 Shared)。
using System;
using System.Threading; public class AsyncDemo {
// The method to be executed asynchronously.
//
public string TestMethod(
int callDuration, out int threadId) {
Console.WriteLine("Test method begins.");
Thread.Sleep(callDuration);
threadId = AppDomain.GetCurrentThreadId();
return "MyCallTime was " + callDuration.ToString();
}
} // The delegate must have the same signature as the method
// you want to call asynchronously.
public delegate string AsyncDelegate(
int callDuration, out int threadId); using System;
using System.Threading; public class AsyncDemo {
// The method to be executed asynchronously.
//
public string TestMethod(
int callDuration, out int threadId) {
Console.WriteLine("Test method begins.");
Thread.Sleep(callDuration);
threadId = AppDomain.GetCurrentThreadId();
return "MyCallTime was " + callDuration.ToString();
}
} // The delegate must have the same signature as the method
// you want to call asynchronously.
public delegate string AsyncDelegate(
int callDuration, out int threadId);
C#异步调用四大方法之使用 EndInvoke 等待异步调用
异步执行方法的最简单方式是以 BeginInvoke 开始,对主线程执行一些操作,然后调用 EndInvoke。EndInvoke 直到C#异步调用完成后才返回。这种技术非常适合文件或网络操作,但是由于它阻塞 EndInvoke,所以不要从用户界面的服务线程中使用它。
public class AsyncMain {
static void Main(string[] args) {
// The asynchronous method puts the thread id here.
int threadId; // Create an instance of the test class.
AsyncDemo ad = new AsyncDemo(); // Create the delegate.
AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod); // Initiate the asychronous call.
IAsyncResult ar = dlgt.BeginInvoke(,
out threadId, null, null); Thread.Sleep();
Console.WriteLine("Main thread {0} does some work.",
AppDomain.GetCurrentThreadId()); // Call EndInvoke to Wait for
//the asynchronous call to complete,
// and to retrieve the results.
string ret = dlgt.EndInvoke(out threadId, ar); Console.WriteLine("The call executed on thread {0},
with return value \"{1}\".", threadId, ret);
}
}
C#异步调用四大方法之使用 WaitHandle 等待异步调用
等待 WaitHandle 是一项常用的线程同步技术。您可以使用由 BeginInvoke 返回的 IAsyncResult 的 AsyncWaitHandle 属性来获取 WaitHandle。C#异步调用完成时会发出 WaitHandle 信号,而您可以通过调用它的 WaitOne 等待它。
如果您使用 WaitHandle,则在C#异步调用完成之后,但在通过调用 EndInvoke 检索结果之前,可以执行其他处理。
public class AsyncMain {
static void Main(string[] args) {
// The asynchronous method puts the thread id here.
int threadId; // Create an instance of the test class.
AsyncDemo ad = new AsyncDemo(); // Create the delegate.
AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod); // Initiate the asychronous call.
IAsyncResult ar = dlgt.BeginInvoke(,
out threadId, null, null); Thread.Sleep();
Console.WriteLine("Main thread {0} does some work.",
AppDomain.GetCurrentThreadId()); // Wait for the WaitHandle to become signaled.
ar.AsyncWaitHandle.WaitOne(); // Perform additional processing here.
// Call EndInvoke to retrieve the results.
string ret = dlgt.EndInvoke(out threadId, ar); Console.WriteLine("The call executed on thread {0},
with return value \"{1}\".", threadId, ret);
}
}
C#异步调用四大方法之轮询异步调用完成
您可以使用由 BeginInvoke 返回的 IAsyncResult 的 IsCompleted 属性来发现C#异步调用何时完成。从用户界面的服务线程中进行C#异步调用时可以执行此操作。轮询完成允许用户界面线程继续处理用户输入。
public class AsyncMain {
static void Main(string[] args) {
// The asynchronous method puts the thread id here.
int threadId; // Create an instance of the test class.
AsyncDemo ad = new AsyncDemo(); // Create the delegate.
AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod); // Initiate the asychronous call.
IAsyncResult ar = dlgt.BeginInvoke(,
out threadId, null, null); // Poll while simulating work.
while(ar.IsCompleted == false) {
Thread.Sleep();
} // Call EndInvoke to retrieve the results.
string ret = dlgt.EndInvoke(out threadId, ar); Console.WriteLine("The call executed on thread {0},
with return value \"{1}\".", threadId, ret);
}
}
C#异步调用四大方法之异步调用完成时执行回调方法
如果启动异步调用的线程不需要处理调用结果,则可以在调用完成时执行回调方法。回调方法在 ThreadPool 线程上执行。
要使用回调方法,必须将代表该方法的 AsyncCallback 委托传递给 BeginInvoke。也可以传递包含回调方法将要使用的信息的对象。例如,可以传递启动调用时曾使用的委托,以便回调方法能够调用 EndInvoke。
public class AsyncMain {
// Asynchronous method puts the thread id here.
private static int threadId; static void Main(string[] args) {
// Create an instance of the test class.
AsyncDemo ad = new AsyncDemo(); // Create the delegate.
AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod); // Initiate the asychronous call. Include an AsyncCallback
// delegate representing the callback method, and the data
// needed to call EndInvoke.
IAsyncResult ar = dlgt.BeginInvoke(,
out threadId,
new AsyncCallback(CallbackMethod),
dlgt ); Console.WriteLine("Press Enter to close application.");
Console.ReadLine();
} // Callback method must have the same signature as the
// AsyncCallback delegate.
static void CallbackMethod(IAsyncResult ar) {
// Retrieve the delegate.
AsyncDelegate dlgt = (AsyncDelegate) ar.AsyncState; // Call EndInvoke to retrieve the results.
string ret = dlgt.EndInvoke(out threadId, ar); Console.WriteLine("The call executed on thread {0},
with return value \"{1}\".", threadId, ret);
}
}
C#异步调用四大方法的基本内容就向你介绍到这里,希望对你了解和学习C#异步调用有所帮助。
[转载]C#异步调用四大方法详解的更多相关文章
- C++调用JAVA方法详解
		
C++调用JAVA方法详解 博客分类: 本文主要参考http://tech.ccidnet.com/art/1081/20050413/237901_1.html 上的文章. C++ ...
 - Python 在子类中调用父类方法详解(单继承、多层继承、多重继承)
		
Python 在子类中调用父类方法详解(单继承.多层继承.多重继承) by:授客 QQ:1033553122 测试环境: win7 64位 Python版本:Python 3.3.5 代码实践 ...
 - C#中异步调用示例与详解
		
using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServi ...
 - vc中调用Com组件的方法详解
		
vc中调用Com组件的方法详解 转载自:网络,来源未知,如有知晓者请告知我.需求:1.创建myCom.dll,该COM只有一个组件,两个接口: IGetRes--方法Hello(), IGet ...
 - Clone使用方法详解【转载】
		
博客引用地址:Clone使用方法详解 Clone使用方法详解 java“指针” Java语言的一个优点就是取消了指针的概念,但也导致了许多程序员在编程中常常忽略了对象与引用的区别,本文 ...
 - Python调用C/C++动态链接库的方法详解
		
Python调用C/C++动态链接库的方法详解 投稿:shichen2014 这篇文章主要介绍了Python调用C/C++动态链接库的方法,需要的朋友可以参考下 本文以实例讲解了Python调用C/C ...
 - 转载  JS组件Bootstrap Select2使用方法详解
		
JS组件Bootstrap Select2使用方法详解 作者:懒得安分 字体:[增加 减小] 类型:转载 时间:2016-01-26我要评论 这篇文章主要为大家介绍了JS组件Bootstrap Sel ...
 - php调用C代码的方法详解和zend_parse_parameters函数详解
		
php调用C代码的方法详解 在php程序中需要用到C代码,应该是下面两种情况: 1 已有C代码,在php程序中想直接用 2 由于php的性能问题,需要用C来实现部分功能 针对第一种情况,最合适的方 ...
 - Android笔记——四大组件详解与总结
		
android四大组件分别为activity.service.content provider.broadcast receiver. ------------------------------- ...
 
随机推荐
- Ubuntu16.04双网卡主备配置
			
前几日写了一篇Ubuntu14.04双网卡主备配置,没成想变化总是这么快,今日安装某软件,提示最匹配的ubuntu版本是16.04,作为一个码农能有什么办法,只能不断去适应变化.拥抱变化. 首先16. ...
 - thinkphp结合layui上传视频
			
JS示例: <script type="text/javascript"> layui.use(['form', 'layedit','element', 'layda ...
 - codeforces 355C - Vasya and Robot
			
因为在允许的情况下,必然是左右手交替进行,这样不会增加多余的无谓的能量. 然后根据不同的分界点,肯定会产生左手或右手重复使用的情况,这是就要加上Qr/Ql * 次数. 一开始的想法,很直接,枚举每个分 ...
 - codeforces 888A/B/C/D/E - [数学题の小合集]
			
这次CF不是很难,我这种弱鸡都能在半个小时内连A四道……不过E题没想到还有这种折半+状压枚举+二分的骚操作,后面就挂G了…… A.Local Extrema 题目链接:https://cn.vjudg ...
 - 冒泡排序之python
			
冒泡排序(Bubble sort) 两两比较相邻记录的关键字,如果反序则交换,直到没有反序记录为止. 1.算法描述: 比较相邻的元素.如果第一个比第二个大,就交换它们两个: 对每一对相邻元素作同样的工 ...
 - ArcCatalog连接ArcSDE连接报:unable to create new database connection file,permission is denied
			
参考博文:链接 ArcCatalog连接ArcSDE连接报:unable to create new database connection file,permission is denied 最近经 ...
 - sublime text3控制台每次报错会显示几行[ ]
			
如下图所示,每次编译报错的时候会显示: 我只需要报错信息,不想红框中的信息出现. 解决方案: 1 找到sublime Text3安装路径下的Default.sublime-package,如~Subl ...
 - [python+opencv] ROI(Range Of Interest)与泛洪填充
			
python+opencv3.3视频教学 基础入门笔记(贾志刚老师) https://www.bilibili.com/video/av24998616/?p=8 ROI(Range Of Inter ...
 - bin/hdfs namenode -format 格式化失败
			
确认配置正确前提下,将name目录删除重建,再格式化: hadoop防止将已经存在的集群格式化
 - HandlerThread分析
			
Handy class for starting a new thread that has a looper. The looper can then be used to create handl ...