我有方法需要跑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);
});
}
如果你给我教程的链接或异步编程的例子,我会非常高兴。我是异步编程的新手,现在尝试学习它们。
答案 0 :(得分:3)
我是异步编程的新手
您的代码没有任何异步。您希望通过在多个线程上运行CPU绑定工作来 parallalize 。
我会重构此代码并使用PLINQ
来实现您的目标。
首先,我会重构AddMeasure
同步,因为它所做的只是使用async over sync anti-pattern。我会让它返回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
没有做太多的工作。
答案 1 :(得分:0)
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);
等待块然而是异步的,所以只需添加任务的继续并等待下面的所有任务。