1

我想获得一个异步委托。我创建了一个简单的代码来了解我的问题在哪里。我一直在阅读 async/await 文档,但所有情况都很简单。

我的代码应用异步委托:

    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 });
                    });
                });
        }
            }
       }
4

1 回答 1

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方法,稍后您可以在该方法上await。这样您就不必在使用事件时执行所需的复杂编排。

现在对话框的使用看起来也更容易了:

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方法中,在await之前。
  • 使用Task.Run将繁重的计算/逻辑卸载到后台线程,并使用await关键字获取任务结果。
  • 在await之后放置所需的计算后逻辑。
  • 为了使用计算结果,等待SelectAsync方法返回的任务,该方法本身被定义为异步(从这种方法返回void是一种不好的做法,但您不想等待似乎任务完成了,所以在这种情况下它是相当安全的)。
于 2013-10-23T09:14:48.983 回答