一次异步运行一个方法

时间:2015-11-24 08:27:08

标签: c# asynchronous async-await task

我有方法需要跑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);
    });
}

如果你给我教程的链接或异步编程的例子,我会非常高兴。我是异步编程的新手,现在尝试学习它们。

2 个答案:

答案 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);

等待块然而是异步的,所以只需添加任务的继续并等待下面的所有任务。