我在C#和相关的async-await模式中为并发而苦苦挣扎。
我面临性能问题,因为我需要使用多个数据库提供程序。
_schedulesProvider
拥有各种提供商。
我真的不想在那里进行任何更改,但是我的想法是同时执行那些昂贵的I / O操作。
我知道在这里使用await异步是比较理想的,这样就不会在等待I / O操作完成时阻止调用线程,但是目前我还没有为此而烦恼。
考虑以下代码:
//queuing all the expensive code in tasks
List<Task> scheduleProviderTasks = _schedulesProvider.Select(scheduleProvider =>
{
return
Task.Run(() =>
{
//expensive I/O operation
var schedules = scheduleProvider.Get();
if (!schedules.Schedules.Any())
{
return;
}
//do some stuff with the result
schedules.Schedules.ForEach(x =>
{
DoSomething(x);
});
});
}).ToList();
//run all tasks
scheduleProviderTasks.ForEach(x=>x.RunSynchronously());
我期望什么:
由于昂贵的操作是并行运行的,因此此操作的成本现在应该低得多。
当前线程被阻塞,直到scheduleProviderTasks.ForEach(x=>x.RunSynchronously());
因此所有操作已完成。
这是真的吗? 我应该重构此代码吗?
答案 0 :(得分:0)
我想知道Task.WaitAll是否对您的情况有所帮助。
这是一个并行执行4 x 1秒任务的示例,总时间为2.6706808秒。
class Program
{
static void Main(string[] args)
{
mStopWatch.Start();
Task[] awaitTasks = mTasks.Select(aTask => Task.Run(() => aTask.TimeConsumingTask())).ToArray();
Task.WaitAll(awaitTasks);
Debug.WriteLine("Done @ " + mStopWatch.Elapsed.ToString());
}
static Stopwatch mStopWatch = new Stopwatch();
static ProviderOfLengthyTask[] mTasks = new ProviderOfLengthyTask[]
{
new ProviderOfLengthyTask("A"),
new ProviderOfLengthyTask("B"),
new ProviderOfLengthyTask("C"),
new ProviderOfLengthyTask("D")
};
class ProviderOfLengthyTask
{
public ProviderOfLengthyTask(string name)
{
Name = name;
}
public readonly string Name;
public void TimeConsumingTask()
{
Thread.Sleep(1000);
Debug.WriteLine("Done with " + Name + " @ " + mStopWatch.Elapsed.ToString());
}
}
}
输出为:
使用B @ 00:00:01.0638455
使用A @ 00:00:01.0673050
以D @ 00:00:02.5961501完成
用C @ 00:00:02.5962068完成
完成@ 00:00:02.6706808