天天看點

Windows Phone 7 異步程式設計模型

Windows Phone 7上的異步程式設計模型其實也就是說把C#裡面的異步程式設計模型在Windows Phone 7應用開發上使用。下面來看一下異步程式設計模型裡面的一些關鍵的概念。

2個方法和一個委托和一個接口:

(1)BeginInvoke方法用于啟動異步調用

Begin 方法包含同步方法簽名中的任何參數,此外還包含另外兩個參數:一個AsyncCallback 委托和一個使用者定義的狀态對象。委托用來調用回調方法,狀态對象是用來向回調方法傳遞狀态資訊。

BeginInvoke立即傳回,不等待異步調用完成。

BeginInvoke傳回IasyncResult,可用于監視調用進度。

(2)EndInvoke方法用于檢索異步調用結果。

End 方法用于結束異步操作并傳回結果,是以包含同步方法簽名中的 ref 和 out 參數,傳回值類型也與同步方法相同。該方法還包括一個 IAsyncResult 參數,用于擷取異步操作是否完成的資訊,當然在使用時就必須傳入對應的 Begin 方法傳回的對象執行個體開始異步操作後如果要阻止應用程式,可以直接調用 End 方法,這會阻止應用程式直到異步操作完成後再繼續執行。也可以使用 IAsyncResult 的 AsyncWaitHandle 屬性,調用其中的WaitOne等方法來阻塞線程。這兩種方法的差別不大,隻是前者必須一直等待而後者可以設定等待逾時。

如果不阻止應用程式,則可以通過輪循 IAsyncResult 的 IsCompleted 狀态來判斷操作是否完成,或使用 AsyncCallback 委托來結束異步操作。AsyncCallback 委托包含一個 IAsyncResult 的簽名,回調方法内部再調用 End 方法來擷取操作執行結果。

在調用BeginInvoke後可随時調用EndInvoke方法,注意:始終在異步調用完成後調用EndInvoke.如果異步調用未完成,EndInvoke将一直阻塞到異步調用完成。

EndInvoke的參數包括需要異步執行的方法的out和ref參數以及由BeginInvoke傳回的IAsyncResult。要注意的是,始終在異步調用完成後調用EndInvoke

(3)AsyncCallback委托用于指定在開始操作完成後應被調用的方法

AsyncCallback委托被作為開始操作上的第二個到最後一個參數傳遞

代碼原型如下:

[Serializable]

public delegate void AsyncCallback(IAsyncResult ar);

(4)IAsyncResult接口

它表示異步操作的狀态.

該接口定義了4個公用屬性

public interface IAsyncResult 

object AsyncState { get; } 

WaitHandle AsyncWaitHandle { get; }

bool CompletedSynchronously { get; } 

bool IsCompleted { get; } 

}

在Windows Phone 7上的應用

AsyncResultNoResult.cs

Windows Phone 7上的異步程式設計模型其實也就是說把C#裡面的異步程式設計模型在Windows Phone 7應用開發上使用。下面來看一下異步程式設計模型裡面的一些關鍵的概念。  

2個方法和一個委托和一個接口:  

(1)BeginInvoke方法用于啟動異步調用  

Begin 方法包含同步方法簽名中的任何參數,此外還包含另外兩個參數:一個AsyncCallback 委托和一個使用者定義的狀态對象。委托用來調用回調方法,狀态對象是用來向回調方法傳遞狀态資訊。  

BeginInvoke立即傳回,不等待異步調用完成。  

BeginInvoke傳回IasyncResult,可用于監視調用進度。  

(2)EndInvoke方法用于檢索異步調用結果。  

End 方法用于結束異步操作并傳回結果,是以包含同步方法簽名中的 ref 和 out 參數,傳回值類型也與同步方法相同。該方法還包括一個 IAsyncResult 參數,用于擷取異步操作是否完成的資訊,當然在使用時就必須傳入對應的 Begin 方法傳回的對象執行個體開始異步操作後如果要阻止應用程式,可以直接調用 End 方法,這會阻止應用程式直到異步操作完成後再繼續執行。也可以使用 IAsyncResult 的 AsyncWaitHandle 屬性,調用其中的WaitOne等方法來阻塞線程。這兩種方法的差別不大,隻是前者必須一直等待而後者可以設定等待逾時。  

如果不阻止應用程式,則可以通過輪循 IAsyncResult 的 IsCompleted 狀态來判斷操作是否完成,或使用 AsyncCallback 委托來結束異步操作。AsyncCallback 委托包含一個 IAsyncResult 的簽名,回調方法内部再調用 End 方法來擷取操作執行結果。  

在調用BeginInvoke後可随時調用EndInvoke方法,注意:始終在異步調用完成後調用EndInvoke.如果異步調用未完成,EndInvoke将一直阻塞到異步調用完成。  

EndInvoke的參數包括需要異步執行的方法的out和ref參數以及由BeginInvoke傳回的IAsyncResult。要注意的是,始終在異步調用完成後調用EndInvoke  

(3)AsyncCallback委托用于指定在開始操作完成後應被調用的方法  

AsyncCallback委托被作為開始操作上的第二個到最後一個參數傳遞  

代碼原型如下:  

[Serializable]  

public delegate void AsyncCallback(IAsyncResult ar);  

(4)IAsyncResult接口  

它表示異步操作的狀态.  

該接口定義了4個公用屬性  

public interface IAsyncResult   

 {    

object AsyncState { get; }   

 WaitHandle AsyncWaitHandle { get; }  

  bool CompletedSynchronously { get; }   

 bool IsCompleted { get; }   

 }   

在Windows Phone 7上的應用  

AsyncResultNoResult.cs  

AsyncResult.cs

using System;  

namespace AsyncTaskDemo  

{  

    public class AsyncResult<TResult> : AsyncResultNoResult  

    {  

        private TResult m_result;//異步操作完成傳回的對象  

        public AsyncResult(AsyncCallback asyncCallback, object state)  

            : base(asyncCallback, state)  

        {  

            this.m_result = default(TResult);  

        }  

        /// <summary> 

        /// 停止異步傳回傳回對象  

        /// </summary> 

        /// <returns></returns> 

        public TResult EndInvoke()  

            base.EndInvoke(); //等待操作完成   

            return m_result;  // 傳回結果  

        /// 操作完成  

        /// <param name="result">傳回結果對象</param> 

        /// <param name="completedSynchronously">是否同步操作</param> 

        public void SetAsCompleted(TResult result, bool completedSynchronously)  

            //儲存異步操作的結果  

            m_result = result;  

            base.SetAsCompleted(null, completedSynchronously);  

    }  

TestTask.cs

using System.Threading;  

    public class TestTask  

        public TestTask()  

        public IAsyncResult BeginTestTask(string text, AsyncCallback asyncCallback, object state)  

            AsyncResult<string> asyncResult = new AsyncResult<string>(asyncCallback, state);  

            ThreadPool.QueueUserWorkItem(DoTestTask, asyncResult);  

            return asyncResult;  

        public string EndTestTask(IAsyncResult asyncResult)  

            return ((AsyncResult<string>)asyncResult).EndInvoke();  

        private void DoTestTask(Object asyncResult)  

            AsyncResult<string> ar = (AsyncResult<string>)asyncResult;  

            try  

            {  

                Thread.Sleep(3000);  

                ar.SetAsCompleted("測試完成", true);  

            }  

            catch (Exception e)  

                ar.SetAsCompleted(e, false);  

MainPage.xaml.cs

TestTask tt = new TestTask();  

        WebTask webTask = new WebTask(new Uri("http://www.cnblogs.com/linzheng"));  

        IAsyncResult ia;  

        public MainPage()  

            InitializeComponent();  

        private void button1_Click(object sender, RoutedEventArgs e)  

            Func<string, IObservable<string>> testResult = Observable.FromAsyncPattern<string, string>(tt.BeginTestTask, tt.EndTestTask);  

            ObservableExtensions.Subscribe<string>(  

               Observable.ObserveOnDispatcher<string> 

               (  

               testResult.Invoke("")  

             ),  

              delegate(string success)  

              {  

                  MessageBox.Show(success);  

              },  

              delegate(Exception exception)  

                  MessageBox.Show(exception.Message);  

              }  

              );  

        } 

運作的效果

本文轉自linzheng 51CTO部落格,原文連結:http://blog.51cto.com/linzheng/1078343

繼續閱讀