繁体   English   中英

C#并发IO请求基础

[英]c# concurrent IO requests basics

我正在为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());

因此,所有操作已完成。

这是真的? 我应该重构此代码吗?

我想知道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完成

用@ 00:00:01.0673050完成

用D @ 00:00:02.5961501完成

用C @ 00:00:02.5962068完成

完成@ 00:00:02.6706808

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM