我对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}";
}
答案 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