提问者:小点点

对等待/异步和任务的说明


最近,我开始使用多线程,并试图更好地理解等待/异步和任务。我输入了以下场景:

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,并且在显示消息框之前仍然要等到该方法被compelte。我研究await,async和Task已经有一段时间了,但似乎不知道如何实现这一点。

对我来说,让button1_Click()使用await async,然后await CreateStuff()方法似乎容易得多。

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

我假设这与返回任务有关,但我不太清楚如何进行。

感谢任何帮助。谢啦!


共2个答案

匿名用户

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

当然可以--但是您需要首先更改的返回类型。目前您返回,这几乎不是一个好主意-它实际上只用于事件处理程序。您只需将其更改为返回,您就可以等待它了:

async Task CreateStuff (List<int> list)

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

await CreateStuff (list);

请注意,并不清楚的实现是否真正理想。您不需要为此使用异步方法-您只需要:

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

当您可以返回任务并让调用代码等待任务时,有一个异步方法仅仅是为了创建一个任务并等待它而存在的,并没有太多意义。(它们确实在某些方面表现得略有不同,但我怀疑,在这种特殊情况下,它们的表现并不重要。)

匿名用户

您的问题是

您需要将更改为,以便可以在调用站点上它。

您应该只将用于事件处理程序。

相关问题