c# - 关于异步任务

标签 c# winforms asynchronous async-await task

我有一个带有按钮和列表框的表单。我想将两个函数的结果添加到列表框中。这两个功能可能需要未知的时间才能完成,我想同时执行它们。一旦其中一个函数完成计算,我想在列表框中显示结果(在另一个函数完成之前)。目前,结果在两个功能完成后显示。我不介意这些函数自己更新列表框。

    async Task<string> LongTaskAsync()
    {
        for(int i = 0; i < 50; i++) {
            Thread.Sleep(100);
        }

        return "Completed long task async";
    }

    async Task<string> ShortTaskAsync()
    {
        for(int i = 0; i < 5; i++) {
            Thread.Sleep(100);
        }

        return "Completed short task async";
    }

    async void BtnRunClick(object sender, EventArgs e)
    {
        listBox1.Items.Clear();

        var longTask = Task.Run(() => LongTaskAsync());
        var shortTask = Task.Run(() => ShortTaskAsync());

        listBox1.Items.Add(await longTask);
        listBox1.Items.Add(await shortTask);        
    }

最佳答案

它同时显示其中 2 个的原因与您如何链接等待有关。

 listBox1.Items.Add(await longTask);
 listBox1.Items.Add(await shortTask); 

在较短的任务之前,您正在等待较长的任务。第二行在长任务完成后运行,此时较短的任务已经完成,这就是您同时看到它们的原因。但在一个您不知道执行什么任务需要更长时间的世界中,您需要有更好的解决方案。

  Action<Task<string>> continuationFunction = t => { this.listBox1.Items.Add(t.Result); };
  Task.Run(() => LongTaskAsync()).ContinueWith(continuationFunction, TaskScheduler.FromCurrentSynchronizationContext()); 
  Task.Run(() => ShortTaskAsync()).ContinueWith(continuationFunction, TaskScheduler.FromCurrentSynchronizationContext());

TaskScheduler.FromCurrentSynchronizationContext() 是为了避免跨线程访问异常。

关于c# - 关于异步任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58889889/

相关文章:

c# - 从 NHibernate 配置文件生成数据库

c# - 为 POST 流式传输 XmlDocument

c# - 如何在 C# 中创建多个对象?

javascript - 在同步方法中等待异步方法?

c# - 即使使用 ConfigureAwait(false),在 WebAPI 中同步调用异步方法也会死锁

python - 使用 asyncore 创建具有客户端/服务器模型的交互式 session

c# - 将指向类的指针从 C# 传递到非托管 C++ 代码

c# - 将二进制字符转换为 jQuery 可以使用的内容

c# - Winforms MVP 网格事件问题

c# - 考虑数字的字符串比较