[C#基础]c#中的BeginInvoke和EndEndInvoke
来源:互联网 发布:4g网络下载慢什么原因 编辑:程序博客网 时间:2024/05/16 05:40
今天初次使用CSDN博客,以往看过无数博客却从未想过自己去写一写,一来觉得自己水平不够,写不出好的学习资料;更重要的时自己的语文功底不行,也不太会组织自己的语言。但现在感觉自己学的东西很容易忘掉,所以还是开个博客来记录一下以后会学到的东西,以便自己回顾自己学过的东西。
现在就记录一下学的C#相关小细节吧。
C#中的多线程和委托相关方法是很有必要学习和掌握的,下面是转载自msdn的相关内容。
手动分割线----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
BeginInvoke方法触发你的异步方法,它和你想要执行的异步方法有相同的参数。另外还有两个可选参数,第一个是AsyncCallback委托是异步完成的回调方法。第二个是用户自定义对象,该对象将传递到回调方法中。BeginInvoke立即返回并且不等待完成异步的调用(继续执行该下面的代码,不需要等待)。BeginInvoke返回IAsyncResult接口,可用于检测异步调用的过程。
通过EndInvoke方法检测异步调用的结果。如果异步调用尚未完成,EndInvoke将阻塞调用线程,直到它完成。EndInvoke参数包括out和ref参数。
下面代码演示使用BeginInvoke和EndInvoke进行异步调用的四种常见方式。在调用BeginInvoke可以做以下工作:
- 做一些其他操作,然后调用EndInvoke方法阻塞线程直到该方法完成。
- 使用IAsyncResult.AsyncWaitHandle属性,使用它的WaitOne方法阻塞线程直到收到WaitHandle信号,然后调用EndInvoke。
- 检查BeginInvoke返回值IAsyncResult的状态来决定方法是否完成,然后调用EndInvoke方法。
- 通过在BeginInvoke方法中传递该委托,在回调方法中调用该委托的EenInvoke方法。
注意
无论你怎么使用,都必须调用EndInvoke方法结束你的异步调用。
下面通过模拟一个耗时的操作,实现上面说的那四种情况。
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading;using System.Threading.Tasks;namespace Wolfy.AsyncDemo{ /// <summary> /// 委托必须和要调用的异步方法有相同的签名 /// </summary> /// <param name="callDuration"></param> /// <param name="threadId"></param> /// <returns></returns> public delegate string AsyncMethodCaller(int callDuration, out int threadId); class Program { static void Main(string[] args) { } static string TestMethod(int callDuration, out int threadId) { Console.WriteLine("Test method begins:"); //睡一会 模拟耗时操作 Thread.Sleep(callDuration); threadId = Thread.CurrentThread.ManagedThreadId; return string.Format("My call time was {0}.", callDuration.ToString()); } }}
情况一:通过EndInovke阻塞线程,直到异步调用结束。
static void Main(string[] args) { int threadId; AsyncMethodCaller caller = new AsyncMethodCaller(TestMethod); IAsyncResult result = caller.BeginInvoke(3000, out threadId, null, null); //调用EndInvoke方法,等待异步嗲用完成,并得到结果。 string returnValue = caller.EndInvoke(out threadId, result); Console.WriteLine("The call executed on thread {0},with return value {1}.", threadId, returnValue); Console.Read(); }
结果
情况二:通过WaitHandle属性阻塞线程。
你可以获得BeginInvoke的返回值的WaitHandle,并使用它的AsyncWaitHanlde属性。WaitHandle信号异步完成时,你可以通过调用WaitOne方法等待。
如果你使用WaitHandle,你可以在之前或者异步调用完成后进行其他的操作。但之后必须使用EndInvoke检查结果。
注意
当你调用EndInvoke方法时,等待句柄并不会自动关闭。如果你释放等待处理的所有引用,当垃圾回收等待句柄是,系统资源将被释放。一旦你完成使用等待句柄,通过WaitHandle的close方法,一次性显示关闭,这时的垃圾回收效率更高。
static void Main(string[] args) { int threadId; AsyncMethodCaller caller = new AsyncMethodCaller(TestMethod); IAsyncResult result = caller.BeginInvoke(3000, out threadId, null, null); Thread.Sleep(0); Console.WriteLine("Main thread {0} does some work.", Thread.CurrentThread.ManagedThreadId); //等待WaitHandle信号 result.AsyncWaitHandle.WaitOne(); //调用EndInvoke方法,等待异步嗲用完成,并得到结果。 string returnValue = caller.EndInvoke(out threadId, result); //关闭等待句柄 result.AsyncWaitHandle.Close(); Console.WriteLine("The call executed on thread {0},with return value {1}.", threadId, returnValue); Console.Read(); }
情况三:检查BeginInvoke返回结果的状态。
可以通过BeginInvoke的返回结果的IsCompleted属性检查异步是否完成。你可以在异步没有完成的时候做其他的操作。
static void Main(string[] args) { int threadId; AsyncMethodCaller caller = new AsyncMethodCaller(TestMethod); IAsyncResult result = caller.BeginInvoke(3000, out threadId, null, null); Thread.Sleep(0); Console.WriteLine("Main thread {0} does some work.", Thread.CurrentThread.ManagedThreadId); while (result.IsCompleted == false) { Thread.Sleep(250); Console.WriteLine("*"); } //调用EndInvoke方法,等待异步嗲用完成,并得到结果。 string returnValue = caller.EndInvoke(out threadId, result); //关闭等待句柄 result.AsyncWaitHandle.Close(); Console.WriteLine("The call executed on thread {0},with return value {1}.", threadId, returnValue); Console.Read(); }
情况四:通过在回调方法中。
如果需要在异步完成后需要做一些其他的操作,你可以在异步完成时执行一个回调方法。在该回调方法中做处理。
首先需要定义一个回调方法。
static void Main(string[] args) { AsyncMethodCaller caller = new AsyncMethodCaller(TestMethod); // The threadId parameter of TestMethod is an out parameter, so // its input value is never used by TestMethod. Therefore, a dummy // variable can be passed to the BeginInvoke call. If the threadId // parameter were a ref parameter, it would have to be a class- // level field so that it could be passed to both BeginInvoke and // EndInvoke. int dummy = 0; // Initiate the asynchronous call, passing three seconds (3000 ms) // for the callDuration parameter of TestMethod; a dummy variable // for the out parameter (threadId); the callback delegate; and // state information that can be retrieved by the callback method. // In this case, the state information is a string that can be used // to format a console message. IAsyncResult result = caller.BeginInvoke(3000, out dummy, TestMethodCallback, "The call executed on thread {0},with return value {1}."); Console.Read(); }
总结
在项目中遇到的有参数又返回值的情况,如何在回调方法中拿到委托和传递的参数,当时卡这里了,后来查看情况四的情况,才得以解决。这里也再学习一下。
- [C#基础]c#中的BeginInvoke和EndEndInvoke
- [C#基础]c#中的BeginInvoke和EndEndInvoke
- C#中的invoke和begininvoke
- C#中的invoke和begininvoke
- C# 中的invoke和begininvoke
- C#中的BeginInvoke和EndInvoke实现异步
- C#中的BeginInvoke和EndInvoke实现异步
- C#中的BeginInvoke和EndInvoke实现异步
- C#中的Invoke和BeginInvoke方法详解
- C#中的线程BeginInvoke和Invoke
- C# 中的Invoke和BeginInvoke机制
- c# Invoke和BeginInvoke
- C# invoke和beginInvoke
- C# invoke和begininvoke
- c# Invoke和BeginInvoke 区别
- c# Invoke和BeginInvoke 区别
- c# Invoke和BeginInvoke 区别
- c# Invoke和BeginInvoke 区别
- C# using 使用方法
- chmod 权限解析
- 【git】git log 格式设置
- 四二、js操作DOM(dom)改变css3属性时封装方法使自动识别浏览器添加css3属性前缀
- [python][库]cPickle库使用方法
- [C#基础]c#中的BeginInvoke和EndEndInvoke
- Linux6.5 安装mysql(rpm包安装)--root用户
- springboot
- ClassNotFoundException: org.springframework.context.event.GenericApplicationListener
- Java:Cookie实现记住用户名、密码
- 关于Mogento 填写运单号后,出现无法保存运送方式“Cannot save shipment.”
- linux 新手学习笔记
- luajit官方性能优化指南和注解
- Android填坑之旅(第十六篇)Android优雅解决App应用异常退出并收集日志供开发者调试(总有你想要的,持续收录中......)