非同步呼叫BeginInvoke()、EndInvoke()
這邊用了3個類別ClassWithDelegate(提供事件讓外部註冊)、FirstSubClass、SecondSubClass(註冊ClassWithDelegate事件)
在執行過程中,發現必須等到FirstSubClass的方法處理完成後,SecondSubClass方法才會執行。
這是因為委派類別的方法Invoke()必須等待事件處理完成後,才能繼續。
所以必須改用BeginInvoke(AsyncCallback callBack, object 呼叫所需方法的委派)、EndInvoke(IAsyncResult ar)
class ClassWithDelegate
{
public delegate int RegisterDelegate(); //定義委派
public event RegisterDelegate MyDel; //將委派作為事件,提供外部註冊
public void Run()
{
for (; ; )
{
if (MyDel!=null) //是否有事件註冊
{
Thread.Sleep(500);
foreach (RegisterDelegate del in MyDel.GetInvocationList())
{
Console.WriteLine("{0}, {1:d}", del.Target, del.Invoke()); //del.Target 取得目前委派用來叫用'執行個體方法'的類別執行個體。
}
}
}
}
}
class FirstSubClass
{
public FirstSubClass(ClassWithDelegate supperClass)
{
supperClass.MyDel += new ClassWithDelegate.RegisterDelegate(supperClass_MyDel); //進行事件註冊
}
int supperClass_MyDel()
{
Thread.Sleep(10000); //停止10秒,模擬在這個事件需要處理大量的資料
return (new Random().Next(1, 100)); //回傳1~100亂數
}
}
class SecondSubClass
{
public SecondSubClass(ClassWithDelegate supperClass)
{
supperClass.MyDel += new ClassWithDelegate.RegisterDelegate(supperClass_MyDel); //進行事件註冊
}
int supperClass_MyDel()
{
return (new Random().Next(101,150)); //回傳101~150亂數
}
}
static void Main(string[] args)
{
ClassWithDelegate superClass = new ClassWithDelegate();
FirstSubClass firstClass = new FirstSubClass(superClass);
SecondSubClass secondClass = new SecondSubClass(superClass);
//當執行方法Run()時,因為FristSubClass、SecondSubClass內部的方法,已經對superClass的委派RegisterDelegate()進行註冊
//所以會執行FristSubClass、SecondSubClass內部的方法,並回傳結果。
superClass.Run();
}
※改用BeginInvoke()、EndInvoke(),BeginInvoke會自行另外建立執行緒,並等待直到完成。
執行後會發現,SecondSubClass不等待FirstSubClass執行完成,而是立即返回結果。
class ClassWithDelegate
{
public delegate int MyDelegate();
public event MyDelegate myDel;
public void Run()
{
for (; ; )
{
if (myDel != null)
{
Thread.Sleep(500);
foreach (MyDelegate del in myDel.GetInvocationList())
{
del.BeginInvoke(new AsyncCallback(EndInvoke), del);
}
}
}
}
private void EndInvoke(IAsyncResult iar)
{
MyDelegate myDel = (MyDelegate)iar.AsyncState;
//委派以object隱藏在IAsyncResult的AsyncState屬性中,將它轉為原類型
int result = myDel.EndInvoke(iar);
Console.WriteLine("{0}, {1:d}", myDel.Target, result);
}
}
class FirstSubClass
{
public FirstSubClass(ClassWithDelegate superClass)
{
superClass.myDel+=new ClassWithDelegate.MyDelegate(CallBack);
}
private int CallBack()
{
Thread.Sleep(10000);
return (new Random().Next(1, 100));
}
}
class SecondSubClass
{
public SecondSubClass(ClassWithDelegate superClass)
{
superClass.myDel += new ClassWithDelegate.MyDelegate(CalBack);
}
private int CalBack()
{
return (new Random().Next(101, 150));
}
}
static void Main(string[] args)
{
ClassWithDelegate superClass = new ClassWithDelegate();
FirstSubClass firstClass = new FirstSubClass(superClass);
SecondSubClass secondClass = new SecondSubClass(superClass);
superClass.Run();
}