在我們的程序中,很多時候會有一些耗時較長的運算,我們為了保證用戶體驗,讓用戶界面能得到及時的響應。我們一般會采用多線程操作,讓耗時操作在
後台完成,比如我們在上傳文件或其他一些需求要在界面顯示進度條的例子。在 .NET2.0中為我們供了一個BackGroundWorker類可以完成類似的需求,具體
使用我們可以參考MSDN。本文要說的我們自己來完成這樣一個功能,並封裝在通用的基類當中。
1.我們封裝的基類如下:
public abstract class MyAsyncBaseClass { //封裝業務方法參數 private class MyMethodParameters { public string StringParameter { get; set; } public int IntParameter { get; set; } public object CallerStateObject { get; set; } public System.Windows.Threading.Dispatcher CallingDispatcher { get; set; } } //當線程執行完成後被激發的事件 public event EventHandler<MyAsyncEventArgs> MyMethodComplete; protected void FireMyMethodCompleteEvent(int result, object state) { if (MyMethodComplete != null) { MyMethodComplete(this, new MyAsyncEventArgs(result, state)); } } //業務邏輯程序 public abstract int MyMethod(string stringParameter, int intParameter); // 異步調用的方法 public void MyMethodAsync(string stringParameer, int intParameter, object state) { //Instantiate the parameter wrapper. MyMethodParameters parameters = new MyMethodParameters() { StringParameter = stringParameer, IntParameter = intParameter, CallerStateObject = state, CallingDispatcher = System.Windows.Threading.Dispatcher.CurrentDispatcher }; //創建線程 System.Threading.ThreadPool.QueueUserWorkItem(MyMethodThreaded, parameters); } // 線程入口點 private void MyMethodThreaded(object p) { MyMethodParameters parameters = (MyMethodParameters)p; //調用實際的MyMethod方法 int result = MyMethod(parameters.StringParameter, parameters.IntParameter); ///Incorect way to raise event ///This would cause a "Cross-thread operation not valid Exception" ///FireMyMethodCompleteEvent(result, parameters.CallerStateObject); /// ///Correct way to raise event ///Construct a new delegate with the signature <int, object> and register ///it on the callers event queue. parameters.CallingDispatcher.BeginInvoke( new Action<int, object>(FireMyMethodCompleteEvent), result, parameters.CallerStateObject ); } }
2.事件參數如下:
public class MyAsyncEventArgs : EventArgs {
/// 用戶狀態對象 public object State { get; protected set; } /// 線程操作完的結果 /// </summary> public int IntResult { get; protected set; } public MyAsyncEventArgs(int result, object state) { State = state; IntResult = result; } }
3.我們具體要實現的類如下:
public class MyClass : MyAsyncBaseClass { public override int MyMethod(string stringParameter, int intParameter) { System.Threading.Thread.Sleep(2000); MessageBox.Show("業務邏輯程序執行的地方"); return 42; } }
4.下面我來做下測試,如下:
public partial class Form1 : Form { protected MyAsyncBaseClass class1; public Form1() { InitializeComponent(); class1 = new MyClass();