如何多线程处理多个文件?

问题描述 投票:0回答:1

我的意思是

如果有100个文件,就会创建100个线程来读取文件并处理文件内容,

当有100个文件时,每秒转一个线程,其余99个不生成线程。

一个文件的一个线程正在运行,99 个线程已关闭。

如果有100个文件,则必须创建100个多线程。

如果有100个文件,有什么方法可以同时处理它们?

        public static void CollectData(CancellationTokenSource cts)
        {
            Task.Run(async () =>
            {
                while (true)
                {
                    try
                    {
                        string shareIp = IniFileHandler.GetPrivateProfile("MOVE_PATH", "PATH", string.Empty, iniFileName);

                        if (shareIp == null || shareIp == "")
                        {
                            log.Error(iniFileName + " 의 폴더명을 기입하시기 바랍니다.");
                            break;
                        }
        
                        FileRead read = new FileRead();
                        await read.getDataTableFromFile(shareIp);                     
        
                    }
                    catch (Exception ex)
                    {
                        log.Error(ex.Message);
                    }
                    finally
                    {
                        await Task.Delay(1000); 
                    }
        
                }
            });
        }
        public async Task getDataTableFromFile(string path)
        {
            try
            {
                string successPath = IniFileHandler.GetPrivateProfile("SUCCESS_PATH", "PATH", string.Empty, iniFileName);
                string failPath = IniFileHandler.GetPrivateProfile("FAIL_PATH", "PATH", string.Empty, iniFileName);
                // string originalPath = IniFileHandler.GetPrivateProfile("SUCCESS_PATH", "PATH", string.Empty, iniFileName);
                DirectoryInfo directoryInfo = new DirectoryInfo(path);
                string fileName = string.Empty;
                string withoutFileName = string.Empty;
                DataTable dt = new DataTable();

                FileInfo[] files = directoryInfo.GetFiles();

                if (directoryInfo.GetFiles().Length > 0)
                {
                    // Console.WriteLine(directoryInfo.GetFiles());
                    foreach (FileInfo file in files)
                    {
                        fileName = file.FullName;
                        withoutFileName = files[0].Name;

                        string fileExtension = Path.GetExtension(fileName);
                        string strLine = string.Empty;
                        string[] strAry = new string[] { };

                        FileStream fs = new FileStream(fileName, FileMode.Open, System.IO.FileAccess.Read, FileShare.Read);

                        try
                        {
                            using (StreamReader reader = new StreamReader(fs, UTF8Encoding.UTF8, true))
                            {
                                if (reader == null)
                                {

                                }

                                if (fileExtension == ".txt")
                                {
                                    strLine = await reader.ReadLineAsync();
                                    strAry = strLine.Split('\t');
                                }
                                else if (fileExtension == ".csv")
                                {
                                    strLine = await reader.ReadLineAsync();
                                    strAry = strLine.Split(',');
                                }
                                else if (fileExtension == ".Log")
                                {
                                    strLine = await reader.ReadLineAsync();
                                    strAry = strLine.Split('\t');
                                    //Console.WriteLine(strAry);
                                }

                                foreach (string str in strAry)
                                {
                                    dt.Columns.Add(str);
                                }
                                while (reader.Peek() >= 0)
                                {
                                    //Console.WriteLine(sr.Peek());
                                    if (fileExtension == ".txt")
                                    {
                                        strLine = await reader.ReadLineAsync();
                                        strAry = strLine.Split('\t');
                                    }
                                    else if (fileExtension == ".csv")
                                    {
                                        strLine = await reader.ReadLineAsync();
                                        strAry = strLine.Split(',');
                                    }
                                    else if (fileExtension == ".Log")
                                    {
                                        strLine = await reader.ReadLineAsync();
                                        strAry = strLine.Split('\t');
                                        //Console.WriteLine(strAry);
                                    }
                                    dt.Rows.Add(strAry);
                                }

                                if (reader.Peek() < 0)
                                {

                                }

                                if (reader.EndOfStream == true)
                                {
                                    reader.Close();

                                    if (InsertDb(dt, fileName, path, successPath, fileExtension) == true)
                                    {
                                        Console.WriteLine(fileName + " 이 " + successPath + " 으로 이동합니다.");
                                        log.Info(fileName + " 이 " + successPath + " 으로 이동합니다.");
                                        moveToSuccess(fileName);
                                    }
                                    else
                                    {
                                        Console.WriteLine(fileName + " 이 " + failPath + " 으로 이동합니다.");
                                        log.Info(fileName + " 이 " + successPath + " 으로 이동합니다.");
                                        moveToFail(fileName);
                                    }

                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            //if (fileName == "") 
                            //{
                            //    Console.WriteLine("폴더에 파일이 없습니다 , 파일을 기입해주세요.");
                            //}2

                        }
                    }
                    //fileName = files[0].FullName;
                }
                
                if (fileName == "")
                {
                    Console.WriteLine("폴더에 파일이 없습니다 , 파일을 기입하세요.");
                    return; 
                }

                //await Task.Delay(1000);
            }
            catch (Exception ex)
            {
                log.Error(ex.Message);
            }
        }
c# multithreading task
1个回答
0
投票

这是一个试错域。如果不尝试,您无法确定同时对 n 个文件执行此操作是否可行。所以你应该尝试一下。测量服务器负载和性能,并尝试同时在服务器上执行某些操作,看看您将服务器绘制到的状态是否可接受。

如果是这样,那就好,因为那毕竟是纸老虎。

但如果没有,请尝试逐渐减少同时运行的线程数量,直到达到可观的状态。

假设您的服务器一次可以正确处理 10 个这样的线程。

这意味着您将始终同时运行 10 个线程(当然,进程结束除外),并且,如果还有其他线程,它们将被排队,因此每当执行一个线程时,都会执行下一个线程队列中将开始。

一种众所周知的方法是重复休眠主线程,并在两次休眠之间检查同时完成的正在运行的线程数量,并从队列中启动该数量的线程。

但是,处理此问题的更好方法是使用

WaitHandle
(请参阅 https://learn.microsoft.com/en-us/dotnet/api/system.threading.waithandle.waitone?view=net-8.0 )与
WaitOne
结合,因此在下一个线程完成时,主线程将恢复其操作并启动下一个线程,然后再次
WaitOne
,直到队列为空。

© www.soinside.com 2019 - 2024. All rights reserved.