本文档只是自己的学习笔记,可能有误,如果有误请大家帮忙指出,谢谢。
如果你想开启一个耗时较长的操作(例如下载文件),但是你又不想这个耗时长的操作会影响接下来其他的操作,那就可以使用BeginInvoke去开启一个单独的线程,让这个耗时长的操作自己玩去吧~(耗时长的操作在这个单独的线程中执行)正常操作继续进行
接下来我用一个简单的流程图表示开启线程的作用
BeginInvoke方法触发你的异步方法,它和你想要执行的异步方法有相同的参数。另外还有两个可选参数,第一个是AsyncCallback委托是异步完成的回调方法。第二个是用户自定义对象,该对象将传递到回调方法中。BeginInvoke立即返回并且不等待完成异步的调用(继续执行该下面的代码,不需要等待)。BeginInvoke返回IAsyncResult接口,可用于检测异步调用的过程。
通过EndInvoke方法检测异步调用的结果。如果异步调用尚未完成,EndInvoke将阻塞调用线程,直到它完成。EndInvoke参数包括out和ref参数。
接下来我将演示4种BeginInvoke和EndInvoke的使用方法
1.直接在主线程中使用EndInvoke获得线程中的返回值
2.使用IAsyncResult.AsyncWaitHandle属性,使用它的WaitOne方法阻塞线程直到收到WaitHandle信号
3. 检查BeginInvoke返回值IAsyncResult的状态来决定方法是否完成,然后调用EndInvoke方法。
4.通过在BeginInvoke方法中传递该委托,在回调方法中调用该委托的EenInvoke方法。
分割线--------------------------------------------------------------------------------------------------------------------------------------
情况1:直接在主线程中使用EndInvoke获得线程中的返回值
class Program
{
static string DownLoad(string controlName)//声明定义一个方法,假设为耗时长的下载文件操作
{
Stopwatch Timer = new Stopwatch();//声明一个计时器,用于计算线程的时间
Timer.Start();//开始计时
for (int i = 1; i <= 10; i++)
{
Console.WriteLine("文件下载中"+i*10+"...");
Thread.Sleep(40);//线程休眠40ms,后继续运行
}
Timer.Stop();//停止计时
Console.WriteLine("文件下载完成,下载文件用时:" + Timer.ElapsedMilliseconds + "毫秒");
return "文件下载完成,下载文件用时:"+Timer.ElapsedMilliseconds+ "毫秒";
}
static void BrowseImg()//声明定义一个方法,假设为耗时短的浏览文件操作
{
Stopwatch Timer = new Stopwatch();//声明一个计时器,用于计算线程的时间
Timer.Start();//开始计时
for (int i = 1; i <= 10; i++)
{
Console.WriteLine("浏览图片中" + i * 10 + "...");
Thread.Sleep(10);//线程休眠10ms,后继续运行
}
Timer.Stop();//停止计时
Console.WriteLine("浏览图片完成,浏览图片用时:" + Timer.ElapsedMilliseconds + "毫秒");
}
static void Main(string[] args)
{
Stopwatch Timer = new Stopwatch();//声明一个计时器,用于计算线程的时间
Timer.Start();//开始计时
Func<string, string> func = DownLoad;
IAsyncResult result= func.BeginInvoke("ljh", null, null);//开启线程执行下载操作
string returnString =