2013-10-23 349 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