一次异步运行一个方法
本文关键字:一个 方法 一次 异步 运行 | 更新日期: 2023-09-27 18:24:15
我有一个方法how需要运行大约68次,等待大约1.2秒。我可以在几个线程中运行这个方法吗?不要等太久。我尝试了这个代码,但仍然太慢。这是我的部分代码
for (byte parameter = 1; parameter < 5; parameter++)
{
for (byte step = 0; step < xValues.Count; step++)
{
await AddMeasure(av, average, parameter, step, time, file);
}
}
CreateDiagram(canGraph, points, xValues, yValues);
这是我的异步方法
private async Task AddMeasure(AverageValue av, Dictionary<DateTime, double> average, byte parameter, byte step, DateTime time, string file)
{
await Task.Run(() =>
{
av.Step = step;
av.KindOfInfo = parameter;
average = av.GetInformationForDiagramBetweenTwoTimes(time, file);
Measure measure = new Measure();
measure.Average = average.FirstOrDefault().Value;
measure.Time = average.FirstOrDefault().Key;
measure.Parameter = parameter;
this.TimeValueParameter.Add(measure);
});
}
如果你能给我教程的链接,或者异步编程的例子,我会非常高兴。我是异步编程的新手,现在试着为他们学习。
我是异步编程的新手
您的代码没有任何异步功能。您希望通过在多个线程上运行CPU绑定工作来并行化。
我会重构这段代码,并使用PLINQ
来实现您想要的。
首先,我会将AddMeasure
重构为同步的,因为它所做的只是使用async over sync反模式。我会让它返回一个Measure
,因为你不能从多个线程并行添加到List<T>
,它是线程不安全的
private Measure CalculateMeasure(AverageValue av, Dictionary<DateTime, double> average,
byte parameter, byte step, DateTime time, string file)
{
av.Step = step;
av.KindOfInfo = parameter;
average = av.GetInformationForDiagramBetweenTwoTimes(time, file);
var first = average.First();
return new Measure
{
Average = first.Value;
Time = first.Key;
Parameter = parameter;
};
}
然后像这样调用它:
List<Measure> measures = Enumerable.Range(0, 6)
.Cast<byte>()
.AsParallel()
.SelectMany(parameter =>
{
var localMeasures = new List<Measure>();
for (byte step = 0; step < xValues.Count; step++)
{
localMeasure.Add(CalculateMeasure(av, average, parameter, step, time, file));
}
return localMeasures;
}).ToList();
this.TimeValueParameter.AddRange(measures);
请注意,当并行时,您应该测量代码,看看它是否真的提高了代码的性能。不要想当然,因为看起来CalculateMeasure
没有做太多工作。
Task[] task = new Task[count];
for (byte parameter = 1; parameter < 5; parameter++)
{
for (byte step = 0; step < xValues.Count; step++)
{
task[index] = AddMeasure(av, average, parameter, step, time, file);
}
}
await Task.WhenAll(task);
但是await块是异步的,所以只需添加任务的延续并等待下面的所有任务。