前言:本篇使用无返回值委托Action做介绍
友情提醒:阅读本篇需有委托的基础知识,小白请跳过。
使用委托
下面这段代码是使用委托的一种方式,一般写代码的时候不会这么写,在此只做案例。
调用invoke执行委托方法,此时主线程被阻塞,需等到委托方法执行完毕才会继续执行下去,和调用普通的接口没什么区别。
那么如何调用委托时,让主线程继续走下去呢?
Action<string> action = DoSomething;
action.Invoke("function");//阻塞主线程
Console.WriteLine("main thread");
公有方法:
public static void DoSomething(string str)
{
System.Threading.Thread.Sleep(3000);
Console.WriteLine($"Read Str:{str}");
}
异步委托
使用beiginInvoke方法,会另起一个线程来执行委托方法,没有特殊设置主线程不会被阻塞。
Action<string> action = DoSomething;
action.BeginInvoke("function", null, null);//另起一个线程,不会阻塞主线程
异步回调
返回值=BeginInvoke(参数1:function para,参数2:callback function,参数3 object)
参数1:委托函数需要的参数
参数2:调用完委托函数,回调的方法
参数3:传给回调函数的参数。下面案例回调函数通过asyncCallBack.AsyncState拿到参数三
BeginInvoke的返回值为callback回调函数的参数
以下代码段中asyncCallBack 和 asyncResult 是同一个对象的同一个实例
Action<string> action = DoSomething;
IAsyncResult asyncResult = null;
AsyncCallback callback = asyncCallBack =>
{
Console.WriteLine(object.ReferenceEquals(asyncCallBack, asyncResult));//true
Console.WriteLine("callback");
Console.WriteLine(asyncCallBack.AsyncState);//callback para
};
asyncResult = action.BeginInvoke("start function", callback, "callback para");
异步等待
方式一
BeginInvoke 的返回值是IAsyncResult类型,它有一个IsCompleted布尔属性,用来判断异步方法是否实行完毕,
根据这个属性值来决定是否等待执行完毕或者进行其他操作
IAsyncResult asyncResult = null;
AsyncCallback callback = asyncCallBack =>
{
Console.WriteLine(asyncCallBack.IsCompleted);//执行到回调函数,一定是true
Console.WriteLine(object.ReferenceEquals(asyncCallBack, asyncResult));
Console.WriteLine("callback");
Console.WriteLine(asyncCallBack.AsyncState);
};
asyncResult = action.BeginInvoke("start function", callback, "callback para");
int i = 0;
while (!asyncResult.IsCompleted)//判断异步方法是否执行完毕,模拟进度条
{
if (i < 9)
{
Console.WriteLine($"正在玩命加载...已完成{++i * 10}%");
}
else
{
Console.WriteLine($"已加载99%");
}
}
Console.WriteLine("加载完成");
方式二
IAsyncResult还有一个对象属性AsyncWaitHandle,
可以用它选择是否等待任务完成 (WaitOne:一直等待异步方法结束再向下执行)
或者 等待多久 就不等了(WaitOne(1000):可自定义等待时间)
IAsyncResult asyncResult;
AsyncCallback callback = asyncCallBack =>
{
Console.WriteLine("callback");
Console.WriteLine(asyncCallBack.AsyncState);
};
Action<string> action = DoSomething;
asyncResult = action.BeginInvoke("hello", callback, "back para");
//asyncResult.AsyncWaitHandle.WaitOne();//等待任务完成
asyncResult.AsyncWaitHandle.WaitOne(1000);//等待1s后继续向下执行