Clarification for Await/Async and Task

本文关键字:and Task Async for Await Clarification | 更新日期: 2023-09-27 17:52:49

最近我开始使用多线程,并一直试图更好地理解await/async和Task。我输入了以下场景:

private void button1_Click(object sender, EventArgs e)
{
    var list = GenerateList();
    progressBar1.Maximum = list.Count ();
    CreateStuff (list));
    MessageBox.Show ("Complete!");
}
async void CreateStuff (List<int> list)
{
    //additional Parameters here used for DoWork()
    await Task.Run (()=>Parallel.ForEach(list, item =>
    {
        DoWork();
        Invoke(new Action(() => progressBar1.PerformStep()));
    }));
    //do something that relies on list
}

我试图使消息框在CreateDocs方法完成后出现。有人告诉我,可以在CreateStuff()方法中继续使用await async,直到方法完成后才显示消息框。我一直在研究await async和Task一段时间,似乎不知道如何做到这一点。

对我来说,似乎更容易使button1_Click()使用await async,然后等待CreateStuff()方法。

我的问题是:是否有可能在CreateStuff方法中继续使用await async,并且在显示消息框之前仍然等待button1_Click()中CreateStuff()方法的完成?

我假设它与返回Task有关,但我不太清楚如何进行。

任何帮助都是感激的。谢谢!

Clarification for Await/Async and Task

我的问题是:是否有可能在CreateStuff方法中继续使用await async,并且在显示消息框之前仍然等待button1_Click()中CreateStuff()方法的完成?

当然可以——但是你需要先改变CreateStuff的返回类型。目前您返回的是void,这几乎从来都不是一个好主意——它实际上只用于事件处理程序。所有你需要做的是改变它返回Task,你可以等待它:

async Task CreateStuff (List<int> list)

然后在点击处理程序中(也需要异步),等待调用它的结果:

await CreateStuff (list);

请注意,CreateStuff的实现并不完全清楚。你不需要async方法——你只需要:

Task CreateStuff(List<int> list)
{
    return Task.Run(() => Parallel.ForEach(list, item =>
    {
        DoWork();
        Invoke(new Action(() => progressBar1.PerformStep()));
    }));
}
有一个异步方法存在只是为了创建一个任务并等待它,当你可以返回任务并让调用代码等待它时,没有太多的意义。(它们在某些方面的行为确实略有不同,但我怀疑在这种特殊情况下没有任何重要的方式。)

你的问题是async void

您需要将CreateStuff()更改为async Task,以便您可以在呼叫站点await

您应该只使用async void作为事件处理程序。