多线程下的IO操作

今天考虑优化项目中文件操作,项目中有许多批量删除文件的操作,当文件很多时,删除操作会比较费时(1s~2s的时间也显得有点慢了),更何况10s以上,想要通过多线程来同时处理多个文件的删除,在程序中使用了ThreadPool和Parallel想要加速删除,但是效果并没有预期的明显,总耗时甚至还有所提升。
先看使用普通循环删除目录的代码:

 var dir = Directory.GetDirectories("D:\\FileStore1\\", "", SearchOption.TopDirectoryOnly);
            Console.WriteLine($"一共{dir.Length}个目录");
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            foreach (var temp in dir)
            {
                //删除目录操作(自己封装的接口,也可使用Directory.Delete方法)
                fileStorage.DeleteDirectory("user", temp.Split("\\").Last());
            }
            stopwatch.Stop();
             Console.WriteLine("耗时:"+stopwatch.ElapsedMilliseconds+"毫秒");
            Console.WriteLine("操作完毕");

运行结果:
多线程下的IO操作_第1张图片
然后我们使用Parallel试一下:

 var dir = Directory.GetDirectories("D:\\FileStore1\\", "", SearchOption.TopDirectoryOnly);
            Console.WriteLine($"一共{dir.Length}个目录");
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            Parallel.ForEach(dir, (temp) =>
            {
                fileStorage.DeleteDirectory("user", temp.Split("\\").Last());
            });
            stopwatch.Stop();
            Console.WriteLine("耗时:"+stopwatch.ElapsedMilliseconds+"毫秒");
            Console.WriteLine("操作完毕");

运行结果:
多线程下的IO操作_第2张图片
可以看到,确实快了6秒左右,但是这和我们的预期差的远,还有一个用ThreadPool执行的,但是无法确定总执行时间,所以就只贴代码算了:

var dir = Directory.GetDirectories("D:\\FileStore1\\", "", SearchOption.TopDirectoryOnly);
            Console.WriteLine($"一共{dir.Length}个目录");
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            foreach (var temp in dir)
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback((obj) =>
                {
                    fileStorage.DeleteDirectory("user", temp.Split("\\").Last());
                })); 
            }
            stopwatch.Stop();
            Console.WriteLine("耗时:"+stopwatch.ElapsedMilliseconds+"毫秒");
            Console.WriteLine("操作完毕");

enmmmm…到底咋回事儿,原本20多秒的操作,用了多线程还是20多秒,这时候我们就应该考虑文件读写操作的底层机制了,要知道刚刚我们的IO操作都是针对磁盘进行操作的,而磁盘操作全靠磁盘的磁头来寻道定位,一个磁盘只有一个磁头(现在计算机磁盘都有多个磁头)
多线程下的IO操作_第3张图片
那么问题来了,我们每个线程都要对磁头进行操作,一个磁头只能为一个线程使用,如果只有一个磁头的话,我们开再多线程也要排队使用啊,所以,对于IO操作使用多线程,具体速度有没有提升,很大程度上取决于磁盘(磁头数),不过,使用多线程确实可以让文件操作在后台运行,提升用户体验。

你可能感兴趣的:(学习路径)