整個非同步呼叫過程中都是圍繞IAsyncResult來進行的,,BeginXXX 返回這個對象,EndXXX接收這個對象來結束當前非同步對象
public interface IAsyncResult
{
WaitHandle AsyncWaitHandle { get; } //阻塞一個線程,直到一個或多個同步對象接收到訊號
Boolean IsCompleted { get; } //判讀當前非同步是否完成
Object AsyncState { get; } //擷取額外的參數值
Boolean CompletedSynchronously { get; } //幾乎沒有使用
}
public class AsyncResult : IAsyncResult, IMessageSink
{
//IAsyncResult 的實現
public virtual WaitHandle AsyncWaitHandle { get; }
public virtual bool IsCompleted { get; }
public virtual object AsyncState { get; }
public virtual bool CompletedSynchronously { get; }
// 其他一些重要的屬性
public bool EndInvokeCalled { get; set; } //檢驗是否調用了EndInvoke()
public virtual object AsyncDelegate { get; } //擷取原始的委派物件
}
ar.AsyncWaitHandle.WaitOne() //阻礙當前線程,直到非同步呼叫結束.
namespace ConsoleApplication15
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("[(#{1}){0}]:Asynchronous Start", DateTime.Now.ToString(), Thread.CurrentThread.ManagedThreadId);
AsyncTest test = new AsyncTest();
ConsoleApplication15.AsyncTest.SalaryEventHandler del = test.YearlySalary;
//使用回呼函數
AsyncCallback callback = new AsyncCallback(OnSalaryCallback);
IAsyncResult ar = del.BeginInvoke(100000, 15, 100000, callback, 2000);
DoAntherJob();
Console.ReadLine(); // 讓黑屏等待,不會直接關閉..
}
//開始其他工作.
static void DoAntherJob()
{
Thread.Sleep(1000);//需要1秒才能完成這個工作,注1
Console.WriteLine("[(#{1}){0}]:Do Another Job", DateTime.Now.ToString(), Thread.CurrentThread.ManagedThreadId);
}
static void OnSalaryCallback(IAsyncResult asyncResult)
{
//通過AsyncState 擷取額外的參數.
decimal para = (int)asyncResult.AsyncState;
//通過AsyncDelegate 擷取原始的委派物件
AsyncResult obj = (AsyncResult)asyncResult;
ConsoleApplication15.AsyncTest.SalaryEventHandler del = (ConsoleApplication15.AsyncTest.SalaryEventHandler)obj.AsyncDelegate;
if (asyncResult.IsCompleted)// 判讀是否已經調用完成
Console.WriteLine("[(#{1}){0}]:Asynchronous Finished.", DateTime.Now.ToString(), Thread.CurrentThread.ManagedThreadId);
decimal val = del.EndInvoke(asyncResult);
Console.WriteLine("[(#{2}){0}]:Output Result:{1}", DateTime.Now.ToString(), val + para, Thread.CurrentThread.ManagedThreadId);
}
}
public class AsyncTest
{
public delegate decimal SalaryEventHandler(decimal salary, int monthCount, decimal bonus); // 對應YearlySalary方法
public decimal YearlySalary(decimal salary, int monthCount, decimal bonus)
{
//類比耗時/複雜的邏輯計算.
Thread.Sleep(3000);//等待3秒,注2
return salary * monthCount + bonus;
}
}
}