了解异步/等待

时间:2015-07-29 18:14:26

标签: c#

我知道如何使用任务等来让它在没有异步/等待的情况下工作,但所有的例子和视频我都看到了我仍然无法理解它。有些人通过在按钮单击中创建任务然后等待该任务来完成它吗?

到目前为止:

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()方法中另一个任务的运行,并在那里返回一个字符串?

1 个答案:

答案 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线程可以自由地做其他事情。