我的意思是
如果有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);
}
}
这是一个试错域。如果不尝试,您无法确定同时对 n 个文件执行此操作是否可行。所以你应该尝试一下。测量服务器负载和性能,并尝试同时在服务器上执行某些操作,看看您将服务器绘制到的状态是否可接受。
如果是这样,那就好,因为那毕竟是纸老虎。
但如果没有,请尝试逐渐减少同时运行的线程数量,直到达到可观的状态。
假设您的服务器一次可以正确处理 10 个这样的线程。
这意味着您将始终同时运行 10 个线程(当然,进程结束除外),并且,如果还有其他线程,它们将被排队,因此每当执行一个线程时,都会执行下一个线程队列中将开始。
一种众所周知的方法是重复休眠主线程,并在两次休眠之间检查同时完成的正在运行的线程数量,并从队列中启动该数量的线程。
但是,处理此问题的更好方法是使用
WaitHandle
(请参阅 https://learn.microsoft.com/en-us/dotnet/api/system.threading.waithandle.waitone?view=net-8.0 )与 WaitOne
结合,因此在下一个线程完成时,主线程将恢复其操作并启动下一个线程,然后再次 WaitOne
,直到队列为空。