请教c 异步 async委托的AsyncWaitHandle.WaitOne的参数作用

 上传我的文档
 下载
 收藏
毕业于医学院校,在医院工作,有相对丰富的护理经验
 下载此文档
正在努力加载中...
异步委托的使用
下载积分:1500
内容提示:异步委托的使用
文档格式:DOCX|
浏览次数:1|
上传日期: 12:45:22|
文档星级:
该用户还上传了这些文档
异步委托的使用
官方公共微信c#线程之异步委托begininvoke、invoke、AsyncWaitHandle.WaitOne 、异步回调 - Dawnlight - 博客园
posts - 16, comments - 2, trackbacks - 0, articles - 1
  单靠自己看书学总是会走很多弯路,任何人也不列外,有些时候自己遇到的很多问题,其它别人在很久之前也可能遇到过,上网查查可以走很大捷径,对自己的学习有很大帮助,刚开始弄线程这块,一开始只是看书,很多东西都是糊里又糊涂。
  首先感谢下这位仁兄的解读,我在这里只做下自己迷惑的地方的解读。
  1,Delegate.BeginInvoke是开起一个新的异步线程执行委托,而Delegate.EndInvoke则是结束这个委托。
  2,Delegate.BeginInvoke总有两个参数,参数一IAsyncResult,一个是Object,这两个参数主要是在异步回调的时候会用得到,这个两个参数总是在参数的最后两位,前几位参数是这个委托对应方法的参数。
  3.Delegate.EndInvoke返回值是委托所对应方法的返回值。如果委托或者方法未执行完毕,则Delegate.EndInvoke会一直处于阻塞状态;委托或者方法执行完毕,则Delegate.EndInvoke开始执行,并得到返回值。
  4,假设IAsyncResult ar = d1.BeginInvoke(1,3000,null,null);则ar.IsCompleted与ar.AsyncHandle.WaitOne(50,flse)具有相同效果,可用来判断改异步委托是否执行完毕。WaitOne(50,flse),50为定义要等待的时间,false为在定义时间内未完成委托时返回值(Bool)
  5.对于异步回调有几个问题需要注意,例如d1.BeginInvoke(1, 3000, TakeAWhileDelegateCompleted, d1);
    ①这个事先执行委托d1(BeginInvoke前的这个d1),后在执行参数的d1,而后在执行TakeAWhileDelegateCompleted方法。
    ②对于参数d1,如果d1是委托或者方法,这执行这个方法,并将返回值作为TakeAWhileDelegateCompleted的参数传递给TakeAWhileDelegateCompleted,而这个IAsyncResult一定是个方法(这样才能执行异步回调),参数的d1也可以是object类型的变量等
    ③TakeAWhileDelegateCompleted是BeginInvoke的IAsyncResult参数,但是TakeAWhileDelegateCompleted这个方法或者委托只有一个参数为IAsyncResult类型,该参数值从BeginInvoke的object参数(d1)获得,在TakeAWhileDelegateCompleted内部,可以用IAsyncResult.AsyncState获得参数值。
    ④对于异步回调,如果主线程结束,则不管委托线程是否结束,所有线程都结束,即如果主线程结束,委托线程未结束,则强迫中止委托线程
  6,Invoke方法直接返回方法或者委托的结果,好比执行了Delegate.BeginInvoke和Delegate.EndInvoke下次自动登录
现在的位置:
& 综合 & 正文
C#异步委托的用法
每个委托都有三个方法:Invoke、BeginInvoke、EndInvoke。第一个方法是委托指定函数的同步调用,另外两个是异步调用。
BeginInvoke方法,调用后立即返回,不等待调用结果。EndInvoke方法,用于检索调用结果。调用BeginInvoke后可随时调用 EndInvoke 方法;如果异步调用未完成,EndInvoke 将一直阻塞到异步调用完成。EndInvoke 的参数包括您需要异步执行的方法的 out 和 ref 参数(在 Visual Basic 中为 &Out& ByRef 和 ByRef)以及由 BeginInvoke 返回的 IAsyncResult
BeginInvoke 异步方法签名的规则是:
包括所有 IN 参数。
包括所有 OUT 参数。
包括所有 IN/OUT 参数。
包括所有 ByRef 参数。
将 AsyncCallback 和 AsyncState(可通过 IAsyncResult 接口的 AsyncState 属性获得)作为最后两个参数。
返回 IAsyncResult。
EndInvoke 异步方法签名的规则是:
包括所有 IN/OUT 参数。
包括所有 OUT 参数。
包括所有 ByRef 参数。
将 IAsyncResult 作为最后一个参数。
从原始方法签名返回原始返回类型。
结果对象 (IAsyncResult) 是从开始操作返回的,并且可用于获取有关异步开始操作是否已完成的状态。结果对象被传递到结束操作,该操作返回调用的最终返回值。在开始操作中可以提供可选的回调。如果提供回调,在调用结束后,将调用该回调;并且回调中的可以调用结束操作。
AsyncCallback 委托
AsyncCallback 委托用于指定在开始操作完成后应被调用的方法。下面是该委托的签名,AsyncCallback 委托被作为开始操作上的第二个到最后一个参数传递:
public delegate void AsyncCallback(IAsyncResult ar);
IAsyncResult 接口
IAsyncResult 接口用于监视和管理异步操作。该接口是从开始操作返回的并被传递到结束操作,以将开始操作和结束操作相关联。如果回调被指定为开始操作的一部分,则 AsyncResult 被传递到回调。以下代码阐释有关 IAsyncResult 接口的属性,该接口可用于监视异步操作的状态并获取还可被传递到开始操作中的异步状态对象:
public interface IAsyncResult
Object AsyncState { }
//该属性为BeginInvoke参数中的最后一个参数对象
WaitHandle AsyncWaitHandle { }
bool CompletedSynchronously { }
bool IsCompleted { }
//该属性判断异步调用是否结束
AsyncState
返回在开始操作方法调用中作为最后一个参数提供的对象。
AsyncWaitHandle
AsyncWaitHandle 属性返回 WaitHandle,后者可用于执行 WaitHandle.WaitOne、WaitAny 或 WaitAll。
直到 AsyncWaitHandle 属性被读取时,实现 IAsyncResult 的对象才需要创建 WaitHandle;执行时间由实施者决定。如果实施者创建了 WaitHandle,则实施者需要负责在适当的时候发出 WaitHandle 信号终止等待。例如,当异步调用的方法返回时,AsyncResult 将代表调用方终止等待。创建后,WaitHandle 应保持活动状态,直到用户调用结束异步操作的方法。此时,可以丢弃 AsyncWaitHandle 后的对象。
CompletedSynchronously
如果开始操作调用已同步完成,则 CompletedSynchronously 属性将被设置为 true。
IsCompleted
在服务器已处理完调用后,IsCompleted 属性将被设置为 true。
调用了 BeginInvoke 后,可以:
进行某些操作,然后调用 EndInvoke 一直阻塞到调用完成。
使用 IAsyncResult.AsyncWaitHandle 获取 WaitHandle,使用它的 WaitOne 方法将执行一直阻塞到发出 WaitHandle 信号,然后调用 EndInvoke。
轮询由 BeginInvoke 返回的 IAsyncResult,确定异步调用何时完成,然后调用 EndInvoke。
将用于回调方法的委托传递给 BeginInvoke。该方法在异步调用完成后在 ThreadPool 线程上执行,它可以调用 EndInvoke。
注: 始终在异步调用完成后调用 EndInvoke。
以下是关于异步委托的测试代码:
using System.T
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);
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(3000,
out threadId, null, null);
Thread.Sleep(0);
Console.WriteLine("Main thread {0} does some work.",
AppDomain.GetCurrentThreadId());
// Wait for the WaitHandle to become signaled.
ar.AsyncWaitHandle.WaitOne();
这个是轮询异步执行状态
// Poll while simulating work.
while(ar.IsCompleted == false)
Thread.Sleep(10);
// 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);
以下代码是用回调函数执行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(3000,
out threadId,
new AsyncCallback(CallbackMethod),
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.AsyncS
// 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);
这里值得顺带一提的是有关Control.Invoke()和Delegate.Invoke()等一系列方法的区别:
Work Thread
Control.Invoke
强制於 UI Thread Control.BeginInvoke
强制於 UI Thread [delegate].Invoke
Call Invoke 的 Thread [delegate].BeginInvoke
新的背景 Thread
&&&&推荐文章:
【上篇】【下篇】1576人阅读
C/C++/C#/dotnet(128)
在应届生找工作的时候,多线程操作几乎是所有的公司都会问及的一个基本问题。
这里做了一个多线程操作的总结,这里总结了通过异步委托来实现多线程操作。
定义一个委托,是创建一个线程的最简单的方法,并且异步调用它。委托是方法的类型安全的引用。同时委托还智齿异步调用方法。
委托使用线程池来完成异步任务。
当自己的程序使用异步委托的时候,委托会自动创建ige执行线程的任务。委托使用线程池完成异步任务,所有的异步委托调用,都会通过调用系统线程池中的线程来完成调用异步任务。
在下面的简单例子中,我们定义了一个异步委托,并在每次输出的时候显示该函数运行在哪个线程中。
在异步委托中,可以使用三种技术来异步的调用委托。下面分别介绍三种调用异步委托的方法。
1. 投票判断异步委托是否完成
在委托中调用BeginInvoke()方法,返回IAsyncResult结果。程序的源代码如下:
该程序的输出结果如图:
可以看到主线程和异步委托线程是同时执行的。
如果在委托结束之前不等待委托完成其他任务就结束主线程,委托线程就会停止。
int result = dl.EndInvoke(ar); 这里的EndInvoke()函数会一直等在异步委托完成并在异步委托完成之前阻断主线程。这样就可以通过这个函数保证异步委托能够正确完成。
2. 等待句柄判断异步委托完成
通过AsyncWatiHandle属性,访问等待句柄。WaitOne()方法阻断当前线程,直到异步调用线程完成返回可以利用的句柄以后再执行当前线程。
运行结果:
ar.AsyncWaitHandle.WaitOne()阻断了当前线程, 直到异步调用线程完成获得可以利用的句柄以后再次执行当前线程。
3. 利用异步回调函数判断异步调用线程是否结束
回调函数的操作比较复杂, 而且对于程序的理解和维护造成非常大的困难。所以一般情况下能不用回调函数就不要使用回调函数。
使用回调函数,必须注意这个函数从委托线程中调用,而不是从主线程中调用回调函数。
运行结果:
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:480337次
积分:6178
积分:6178
排名:第2658名
原创:94篇
转载:181篇
评论:80条
(2)(1)(6)(3)(2)(2)(1)(8)(4)(2)(1)(1)(1)(2)(1)(1)(2)(3)(1)(3)(2)(1)(2)(3)(1)(4)(3)(1)(2)(2)(2)(1)(1)(7)(5)(3)(3)(7)(3)(5)(2)(1)(1)(1)(2)(2)(1)(1)(2)(3)(1)(1)(2)(1)(6)(2)(2)(7)(6)(1)(8)(5)(2)(2)(2)(4)(2)(5)(4)(1)(2)(2)(1)(2)(1)(2)(4)(2)(2)(1)(1)(2)(2)(5)(4)(4)(3)(4)(6)(2)(4)(3)(3)(5)(6)(7)(13)第二章、线程和同步(2.2、异步委托)_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
第二章、线程和同步(2.2、异步委托)
上传于||暂无简介
阅读已结束,如果下载本文需要使用5下载券
想免费下载本文?
下载文档到电脑,查找使用更方便
还剩2页未读,继续阅读
你可能喜欢

我要回帖

更多关于 c async task 异步 的文章

 

随机推荐