Invoke与Begining的区别:
Invoke会阻塞当前线程,知道invoke结束才会去执行下面的代码。
而BeginInvoke则可以异步调用,也就是方法封送完后马上返回,不必等待执行结束,调用的线程不会被阻塞。
调用者可以使用EndInvoke或者其它类似WaitHandle机制等待异步操作的完成。
先说下Invoke
class Program
{
static void Main(string[] args)
{
MyProgram mp = new MyProgram();
mp.removeUser("12a");
}
}
public class MyProgram
{
public delegate string myDelegate(string logTxt);
public void removeUser(string userid)
{
///方法体
myDelegate deleg = new myDelegate(Utils.postLog);
string gres=deleg.Invoke("这个是方法的参数");//这个是方法的参数
int a = 1;
int b = 2;
int c = 3;
Console.WriteLine(a+b+c);
Console.WriteLine(gres);
Console.ReadKey();
}
}
public class Utils
{
public static string postLog(string logTxt)
{
string res = string.Empty;
///方法体
Thread.Sleep(5000);//线程休息5秒,模拟request请求延迟
res = "OK";
return res;
}
}这里Invoke 必须等委托函数调用完成之后,才会执行后面操作,那么当我们的委托函数执行的是一个非常耗时的操作
这样线程就会被阻塞,造成用户操作卡顿的情况,所以,为了解决invoke同步的问题,还有一种就是beginInvoke
BeginInvoke方法触发你的异步方法,它和你想要执行的异步方法有相同的参数。另外还有两个可选参数,第一个是AsyncCallback委托是异步完成的回调方法。第二个是用户自定义对象,该对象将传递到回调方法中。BeginInvoke立即返回并且不等待完成异步的调用(继续执行该下面的代码,不需要等待)。BeginInvoke返回IAsyncResult接口,可用于检测异步调用的过程。
通过EndInvoke方法检测异步调用的结果。如果异步调用尚未完成,EndInvoke将阻塞调用线程,直到它完成。EndInvoke参数包括out和ref参数。
不管怎么么样,调用了beginInvoke ,就必须调用endInvoke 结束异步,
那我们怎么才能知道什么时候异步结束呢,常见四种方法:
1、做一些其他操作,然后调用EndInvoke方法阻塞线程直到该方法完成。
2、使用IAsyncResult.AsyncWaitHandle属性,使用它的WaitOne方法阻塞线程直到收到WaitHandle信号,然后调用EndInvoke。
3、检查BeginInvoke返回值IAsyncResult的状态来决定方法是否完成,然后调用EndInvoke方法。
4、通过在BeginInvoke方法中传递该委托,在回调方法中调用该委托的EndInvoke方法。
下面是BeginInvoke
class Program
{
static void Main(string[] args)
{
MyProgram mp = new MyProgram();
mp.removeUser("12a");
}
}
public class MyProgram
{
public delegate string myDelegate(string logTxt);
public void removeUser(string userid)
{
///方法体
myDelegate deleg = new myDelegate(Utils.postLog);
IAsyncResult res = deleg.BeginInvoke("用户1删除成功", null, null); //参数各自是 委托的参数(可能有多个),执行后的回调(不需要可以null),异步状态
int a = 1;
int b = 2;
int c = 3;
Console.WriteLine(a+b+c);
string gres = deleg.EndInvoke(res);
Console.WriteLine(gres);
Console.ReadKey();
}
}
public class Utils
{
public static string postLog(string logTxt)
{
string res = string.Empty;
///方法体
Thread.Sleep(5000);//线程休息5秒,模拟request请求延迟
res = "OK";
return res;
}
}
微信扫码查看本文
发表评论