一次异步运行一个方法

本文关键字:一个 方法 一次 异步 运行 | 更新日期: 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块是异步的,所以只需添加任务的延续并等待下面的所有任务。