C# 异步函数 - 尝试在 foreach 循环中对值求和

标签 c# asynchronous

我的 CalcTime 函数有问题,我尝试以异步方式对事件中的所有值求和,但我 得到错误的值,我想要 60 秒,但每次运行都会得到不同的值:

async Task main()
{
    // do stuff
    Task timeTask = class1.CalcTime();
    await Task.WhenAll(timeTask);

}

public class class1 {
    // In events lists have 6 events and each event is 10 seconds
    public async Task CalcTime()
    {
        double actTime  = 0;
        List<Task<double>> list = new List<Task<double>>();
        foreach (Event event in events)
        {
            list.Add(Task.Run(() => actTime += ReturnTime(event)));
        }    

            await Task.WhenAll(list);
        
            // actTime gets a different value in each run, why?
    }

    public double ReturnTime(Event event)
    {
       return event.Time;
    }

}

为什么会发生这种情况?以及如何修复它?

还有更多问题, 如果我在函数内部使用 Task.WhenAll 并且在主函数中调用此函数之后 我还需要在 main 中将 Task.WhenAll 设置为这个特定函数? 还是只在函数中调用它就足够了?

如果我将await词与Task.WhenAll一起使用,那么函数就会停止,直到所有工作完成 或 Task.WhenAll 等待所有作业完成,同时线程可用于另一个作业 并可以继续在主函数中工作吗?

谢谢!

最佳答案

正如canton7所说in a comment ,您可以通过收集每个 Task<double> 的结果来避免所有线程安全陷阱。 ,并在所有任务完成后对部分结果求和。这样,任务就不会通过尝试以不同步的方式更新共享变量而互相踩踏。

var tasks = new List<Task<double>>();
foreach (var event in events)
{
    tasks.Add(Task.Run(() => ReturnTime(event)));
}    
double[] results = await Task.WhenAll(tasks);
double actTime = results.Sum();

关于C# 异步函数 - 尝试在 foreach 循环中对值求和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64661928/

相关文章:

c# - Excel 服务无法打开工作簿

java - GAE - 我应该链接异步回调吗?

Python Asyncio 任务取消

javascript - 基本异步等待javascript

javascript - 在迭代具有内部异步代码的对象循环的对象时,如何正确跟踪变量?

c# - 处理来自线程的值 执行yield return函数

c# - JSON 主体未被 NancyModule 反序列化

c# - 如何在运行时检查操作系统版本,例如在 Windows 或 Linux 上,不使用条件编译语句

c# - C#.NET 项目中我们真的需要 ApplicationInsights.config 文件吗?

c# - 在 C# 中处理大文件时出现内存不足异常