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; } }

微信扫码查看本文
发表评论