异步类委托(async / await)

时间:2013-10-23 08:06:01

标签: c# asynchronous delegates async-await

我想获得一个异步委托。我创建了一个简单的代码来了解我的问题在哪里。我一直在阅读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 });
                    });
                });
        }
            }
       }

1 个答案:

答案 0 :(得分:3)

问题在于你的整体方法。您不应该使用基于事件的API,您应该使用基于continuation的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 ();
}

总结一下:

  • await 之前,将所需的UI准备逻辑放在 SelectAsync 方法中。
  • 使用 Task.Run 将大量计算/逻辑卸载到后台线程,并使用 await 关键字获取任务结果。
  • 等待之后放置所需的计算后逻辑。
  • 为了使用计算结果,等待 SelectAsync 方法返回的任务中,该方法本身被定义为 async (从这样的方法返回 void 是一种不好的做法,但是你似乎不想等待任务的完成,所以在这种情况下这是非常安全的。)