首页 文章

Await / Async和Task的澄清

提问于
浏览
1

最近我开始使用多线程,并一直在努力更好地理解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()方法中可以继续使用等待异步,并且在我显示消息框之前仍然等到方法强制执行 . 我一直在研究等待异步和任务一段时间,似乎无法弄清楚如何做到这一点 .

对我来说,使button1_Click()使用await async,然后等待CreateStuff()方法似乎要容易得多 .

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

我假设它与返回任务有关,但我无法弄清楚如何进展它 .

任何帮助表示赞赏 . 谢谢!

2 回答

  • 6

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

    绝对 - 但您需要首先更改 CreateStuff 的返回类型 . 目前你正在返回 void ,这几乎不是一个好主意 - 它真的只适用于事件处理程序 . 您需要做的就是将其更改为返回 Task ,您可以等待它:

    async Task CreateStuff (List<int> list)
    

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

    await CreateStuff (list);
    

    一点都不清楚 CreateStuff 的实施是非常理想的,请注意 . 你不需要异步方法 - 你可以只有:

    Task CreateStuff(List<int> list)
    {
        return Task.Run(() => Parallel.ForEach(list, item =>
        {
            DoWork();
            Invoke(new Action(() => progressBar1.PerformStep()));
        }));
    }
    

    如果只是为了创建一个任务并等待它,那么就没有太多意义了,当你可以只返回任务并让调用代码等待它时 . (我怀疑,它们在某些方面的表现略有不同,但在这种特殊情况下并不重要 . )

  • 2

    你的问题是 async void .

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

    您应该只将 async void 用于事件处理程序 .

相关问题