我知道如何使用任务等来让它在没有异步/等待的情况下工作,但所有的例子和视频我都看到了我仍然无法理解它。有些人通过在按钮单击中创建任务然后等待该任务来完成它吗?
到目前为止:
private async void button1_Click(object sender, EventArgs e) {
var vari = await GetId();
comboBox1.Items.Add(vari);
}
private Task<string> GetId() {
return Task.Run(() => {
return getstring();
});
}
public string getstring() {
Thread.Sleep(5000);//simulate long task
string d = "Example";
return d;
}
我尝试了几种不同的方式,这是正确的做法吗?有没有办法可以消除GetId()
方法中另一个任务的运行,并在那里返回一个字符串?
答案 0 :(得分:5)
有没有办法可以消除GetId()方法中另一个任务的运行,只返回一个字符串?
Task.Run
只对新线程执行操作。如果你不这样做并直接调用GetId
,它将只在UI线程上运行,阻止用户界面5秒钟。
只是标记方法async
并不能使它在新线程上运行,它只表示该方法使用await
。如果你这样做了:
private async void button1_Click(object sender, EventArgs e) {
var vari = await GetId();
comboBox1.Items.Add(vari);
}
private async Task<string> GetId() {
Thread.Sleep(5000);//simulate long task
string d = "Example";
return d;
}
它会编译(带有警告因为GetId
没有使用await
),但它会在UI线程上同步执行。
然而,您可以做的是将Thread.Sleep
(同步)替换为Task.Delay
(这是异步的):
private async void button1_Click(object sender, EventArgs e) {
var vari = await GetId();
comboBox1.Items.Add(vari);
}
private async Task<string> GetId() {
await Task.Delay(5000); //simulate long task
string d = "Example";
return d;
}
在这种情况下,不涉及新的线程。在后台,Task.Delay
只设置一种计时器,当延迟时间结束时,该计时器将执行方法的其余部分(await
之后)。在此期间,UI线程可以自由地做其他事情。