我的 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/