其实无论C#还是Java实现异步的本质都还是多线程。只不过C#里用委托来封装起来了这个多线程。对于调用者是透明的,看不到的。下面就分别用C#和java实现最简单和基本的异步调用,然后对于子线程对主线程的更新操作都是通过回调方法来实现的。
C#的异步调用
在C#中使用线程的方法很多,使用委托的BeginInvoke和EndInvoke方法就是其中之一。BeginInvoke方法可以使用线程异步地执行委托所指向的方法。然后通过EndInvoke方法获得方法的返回值(EndInvoke方法的返回值就是被调用方法的返回值),或是确定方法已经被成功调用。我们可以通过四种方法从EndInvoke方法来获得返回值
public class Program
{
private static int i = 0;
public static void Main(string[] args)
{
BigWorkDelegate bigWork = new TestB().BigWork;//需要异步执行的方法
AsyncCallback callBack = CallBack;//异步操作完成后的更新主线程的回调方法
IAsyncResult result = bigWork.BeginInvoke(3000, callBack, bigWork);
// 调用EndInvoke方法,主线程将被阻塞3秒
//int i = bigWork.EndInvoke(result);
//Console.WriteLine("123");
Console.ReadLine();
}
public static void CallBack(IAsyncResult result)
{
if (result == null)
return;
i = (result.AsyncState as BigWorkDelegate).EndInvoke(result);
Console.WriteLine("这是费时工作完了后的回调操作:结果="+i);
}
}
public delegate int BigWorkDelegate(int second);
/// <summary>
/// 子线程中调用
/// </summary>
public class TestB
{
public int BigWork(int second)
{
Console.WriteLine("开始费时工作...");
//模拟耗时操作
Thread.Sleep(second);
Console.WriteLine("工作完成");
return 1;
}
}
java的异步调用
package com.rxb;
public class AsyncTask implements ICallBack {
private int result = 0;
public static void main(String[] args) {
// TODO Auto-generated method stub
Thread thread = new Thread(new TestB(new AsyncTask(),2000));
thread.start();
System.out.println("主线程走完了");
}
//主线程的回调方法,对于GUI程序可以在这里更新主线的UI
@Override
public void callBack(int i) {
// TODO Auto-generated method stub
result = i;
System.out.println("异步操作返回的结果:"+result);
}
}
//回掉接口
interface ICallBack{
void callBack(int i);
}
class TestB implements Runnable {
private int second = 0;
private ICallBack callBack;
public TestB(ICallBack callBack,int mil){
this.callBack = callBack;
this.second = mil;
}
//这是一个模拟耗时操作的方法
public void run() {
System.out.println("开始耗时操作......");
try {
Thread.sleep(second);
//子线程完成后通过回调函数通知主线程
callBack.callBack(2);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("耗时操作完成!");
}
}