程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 關於異步方法調用

關於異步方法調用

編輯:C#入門知識

在我們的程序中,很多時候會有一些耗時較長的運算,我們為了保證用戶體驗,讓用戶界面能得到及時的響應。我們一般會采用多線程操作,讓耗時操作在
後台完成,比如我們在上傳文件或其他一些需求要在界面顯示進度條的例子。在 .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.下面我來做下測試,如下:

image

 

public partial class Form1 : Form
    {
       protected MyAsyncBaseClass class1;

        public Form1()
        {
            InitializeComponent();
            class1 = new MyClass();    						

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved