Reputation: 382
I have method how need running around 68 times, and this is waiting around 1.2 seconds. Can I running this method in few threads for not wait too much. I try this code but is still too slow. This is my part of code
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);
And this is my async method
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);
});
}
I would be very greatful if you give me the link for tutorial, or examples with asynchronous programming. I'm new in asynchronous programming and try now to learn for them.
Upvotes: 0
Views: 137
Reputation: 149518
I'm new in asynchronous programming
There is nothing asynchronous about your code. You want to parallalize it by running CPU bound work on multiple threads.
I would refactor this code and use PLINQ
to achieve what you want.
First, I would refactor AddMeasure
to be synchronous, because all it's doing is using the async over sync anti-pattern. I would make it return a Measure
, because you can't add to a List<T>
in parallel from multiple threads, it isn't thread-safe.
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;
};
}
And then invoke it like this:
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);
Note that when going parallel, you should measure your code and see if you it actually improves the performance of your code. Don't take it for granted, as it looks like CalculateMeasure
isn't doing too much work.
Upvotes: 3
Reputation: 2880
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 blocks however is asynchronous, so just add continuation of tasks and await all of them below.
Upvotes: 0