2013-10-23 342 views
1

我想獲得一個異步委託。我創建了一個簡單的代碼來了解我的問題在哪裏。我一直在閱讀異步/等待文檔,但所有情況都很簡單。異步類委託(異步/等待)

我的代碼申請異步委託:

public override void ViewDidLoad() 
    { 
     base.ViewDidLoad(); 

     int code; 
     CustomDialog dialog = new CustomDialog (this); 
     dialog.Select(); 

     dialog.Finish += (t) => 
     { 
      code = t.code; 
     }; 

      // 
      //Wait until app executes dialog.finish(). 
      //I don't want put the UIAlertView in "dialog.Finish". 
      // 

     UIAlertView alert = new UIAlertView ("dialog later", "item select " + code, null, null, "ok"); 
     alert.Show(); 
     } 

    public class CustomType 
    { 
     public int code { get; set; } 
    } 

    public class CustomDialog 
    { 
     public event DialogoEventHandle Finish; 
     public delegate void DialogoEventHandle (CustomType t); 
     private UIViewController view; 

     public CustomDialog(UIViewController view) 
     { 
      this.view = view; 
     } 

     protected void OnFinish(CustomType t) 
     { 
      if (Finish != null) 
       Finish(t); 
     } 


     public void Select() 
     { 
       ThreadPool.QueueUserWorkItem ((object sender) => 
       { 
        //operation 
        Thread.Sleep (400); 

        this.view.InvokeOnMainThread (() => 
        { 
         OnFinish (new CustomType() { code = 5 }); 
        }); 
       }); 
     } 
      } 
     } 
+0

方法'CalculateAsync'被命名爲異步,但真的不是 –

+0

@SriramSakthivel謝謝,但我有OnFinish委託的問題。 – DesarrollosDD

回答

3

問題是與你的整體辦法。你不應該使用基於事件的API,你應該使用基於延續的API。所以,你的對話變得簡單多了:

public class CustomDialog 
{ 
    public async Task<CustomType> SelectAsync() 
    { 
     //perform some work on the UI thread 

     var customTypeInstance = await Task.Run(
      () => 
      { 
       //operation 
       Thread.Sleep(400); 

       return new CustomType {code = 5}; 
      }); 

     //perform some more work on the UI thread, using the received instance 
     return customTypeInstance; 
    } 
} 

在這裏,你引入一個異步SelectAsync方法上,您可以在以後等待。這樣,您不必在使用事件時執行所需的複雜業務流程。

現在對話框的消費會顯得更容易,以及:

public override void ViewDidLoad() 
{ 
    base.ViewDidLoad(); 

    ShowAlertOnSelectCompletion(new CustomDialog()); 
} 

private async void ShowAlertOnSelectCompletion(CustomDialog dialog) 
{ 
    var customType = await dialog.SelectAsync(); 

    UIAlertView alert = new UIAlertView ("dialog later", "item select " + customType.code, null, null, "ok"); 
    alert.Show(); 
} 

概括起來:

  • 將所需的UI編寫邏輯SelectAsync方法裏面,前等待
  • 使用Task.Run將大量計算/邏輯卸載到後臺線程,並使用等待關鍵字獲得任務結果。
  • 等待後所需的後期計算邏輯。
  • 爲了使用計算結果,等待該任務從的方法內的SelectAsync方法,其通過本身被定義爲異步返回(從這樣的方法返回空隙是一種不好的做法,但你不想等待任務完成,看來,所以在這種情況下它是非常安全的)。
+0

哦,謝謝。這是一個很好的答案。 – DesarrollosDD

+0

你不需要'Select()'中的'async'和'await',直接返回'Task'。此外,該方法應該被稱爲'SelectAsync()'。 – svick

+0

@svick謝謝,你是對的,修復它。 – galenus