是async await结构中必需的包装器

时间:2017-05-10 06:44:22

标签: c#

我对C#比较新,我一直在学习异步编程。所以我一直在尝试使用标签和按钮创建一个简单的UI,当我按下按钮时,标签文本会发生变化,我被教会这样做:

private void button1_Click(object sender, EventArgs e)
        {
            CallChangeLable();
            label1.Text = "Loading ...";
        }

        private async void CallChangeLable()
        {
            var result = await ChangeLabelAsync("Oliver");
            label1.Text = result;
        }

        private Task<string> ChangeLabelAsync(string name)
        {
            return Task.Run(() => ChangeLable(name));
        }

        private string ChangeLable(string name)
        {
            Thread.Sleep(2000);
            return $"Hi {name}";
        }

现在我在没有包装步骤的情况下尝试了这段代码:

private Task<string> ChangeLabelAsync(string name)
        {
            return Task.Run(() => ChangeLable(name));
        } 

当然我将task.run方法移动到其他地方并修改了命名,代码仍然正常,UI仍然响应。我的问题是,为什么包装步骤很重要,我可以跳过吗?

以下是修改后的代码:

private void button1_Click(object sender, EventArgs e)
        {
            CallChangeLable();
            label1.Text = "Loading ...";
        }

        private async void CallChangeLable()
        {
            var result = await Task.Run(() => ChangeLable("Mahmoud"));
            label1.Text = result;
        }

        private string ChangeLable(string name)
        {
            Thread.Sleep(2000);
            return $"Hi {name}";
        }

3 个答案:

答案 0 :(得分:0)

好吧,你想确保不阻止UI线程 - 所以不要跳过它。

Stephen Cleary有一些关于这个主题的优秀文章: https://blog.stephencleary.com/2013/11/taskrun-etiquette-examples-dont-use.html

对于Async / Await编程,一般来看看Stephen Cleary的旧msdn帖子的最佳实践: https://msdn.microsoft.com/en-us/magazine/jj991977.aspx

希望有所帮助。

答案 1 :(得分:0)

使用SynchronizationContext你可以做这样的事情

private async void button1_Click(object sender, EventArgs e)
    {
        SynchronizationContext.Current.Post((txt)=>{
        label1.Text = txt;

}, “加载......”);         }

答案 2 :(得分:0)

  

我的问题是,为什么包装步骤很重要,我可以跳过吗?

实际上,你不应该有一个包装器。 Providing a fake-asynchronous method is an antipattern