- Регистрация
- 17.09.2022
- Сообщения
- 15
- Благодарностей
- 2
- Баллы
- 3
Всем привет, третий день бьюсь с проблемой. Я никогда не работал с многопотоком тем более на C#, решил начать с простенького проекта для которого я попросил chatgpt написать код, и вроде бы он даже работает во многопотоке но меня беспокоит что иногда вижу ошибки записи в фаил.
Сам проект сначала берёт рандомный фаил из папки(в папке ~100 фаилов по 1mb) и берёт из этого фаила строку с удалением. Тут вроде бы всё нормально и срабатывает механизм lock если я правильно понимаю суть его работы.
Следующий экшен тоже в C# кубике делает Get запрос на полученную строку из фаила, разбивает ответ на заголовки и содержимое
Следующий экшен берёт последний статус код из заголовка
Потом идёт кубик C# который парсит тело ответа на разные условия и в зависимости от найденного условия делает запись в нужный фаил
пример условий:
{ "<title>Access denied</title>", "Access-denied.txt" },
{ "<title>Request Rejected</title>", "Access-denied.txt" },
{ "<h1>Not Found</h1>", "Not-Found.txt" },
{ "<title>404 Not Found</title>", "Not-Found.txt" },
{ "<title>Domain Suspension</title>", "Domain-Expired.txt" },
{ "<title>Account Suspended</title>", "Domain-Expired.txt" },
если ничего не спарсилось то тогда происходит запись в фаил Unknown.txt
всё бы ничего но тут какая то ошибка, потому что зенка пишет:
Выполнение действия CSharp OwnCode: Parsing All stuff. Процесс не может получить доступ к файлу "E:\BASE\(другой софт)\BadUrlsSorter\files\output\Unknown.txt", так как этот файл используется другим процессом.
Из чего я делаю вывод что некоторые строки не записываются, хотя сам процесс идёт довольно бодро и все фаилы наполняються визуально достаточно быстро. Я запускаю этот проект в 200 потоков и вижу как иногда лезут ошибки.
Как мне исправить код, чтобы он не терял строки и записывал их в указанные фаилы?
Я пытался всё это время исправить этот код в chatgpt но он упорно подсовывает мне один и тот же код либо иногда пишет код который я так понимаю надо записывать там где записываются директивы using, я с этим ещё не работал и не разбирался, для меня это очень сложно.
Из сложившейся ситуации я сделал вывод что строки теряются потому что на запись тоже нужно делать lock. Я никогда не работал с этим, могу что то не так интерпритировать, но с chatgpt это не вывозит, помогите плиз кто чем может.
Сам проект сначала берёт рандомный фаил из папки(в папке ~100 фаилов по 1mb) и берёт из этого фаила строку с удалением. Тут вроде бы всё нормально и срабатывает механизм lock если я правильно понимаю суть его работы.
C#:
string inputDir = project.Directory + @"\files\input\";
project.Variables["inputDir"].Value = inputDir;
string outputDir = project.Directory + @"\files\output\";
project.Variables["outputDir"].Value = outputDir;
// Берём рандомный фаил из директории
//var inputDir = $"{project.Directory}{project.Variables["inputDir"].Value}";
var inputFile = ZennoLab.Macros.FileSystem.DirectoryRandomFile(inputDir);
// Проверяем количество файлов
if (inputFile.Length == 0)
{
throw new Exception($"Не найдено ни одного файла в папке: {inputDir}");
}
project.Variables["inputFile"].Value = inputFile;
// Получаем имя файла
string fileName = Path.GetFileName(inputFile);
project.Variables["fileName"].Value = fileName;
Следующий экшен тоже в C# кубике делает Get запрос на полученную строку из фаила, разбивает ответ на заголовки и содержимое
C#:
var proxy = project.GetProxy(); // Получаем прокси проекта
var timeout = 7000;
//Сам запрос
var response = ZennoPoster.HTTP.Request(
ZennoLab.InterfacesLibrary.Enums.Http.HttpMethod.GET, project.Variables["inputLink"].Value, "", "", proxy, "UTF-8",
ZennoLab.InterfacesLibrary.Enums.Http.ResponceType.HeaderAndBody, timeout, "", project.Profile.UserAgent, true, 5,
new String[]{}, "", false, false, project.Profile.CookieContainer);
// Обрабатываем полученный ответ сервера
response = response.Trim();
// Разделитель заголовков и содержимого
string[] separator = new string[] { "\r\n\r\n" };
// Массив заголовков и содержимого (содержимое тоже может быть разбито на части)
string[] headersAndBody = response.Split(separator, StringSplitOptions.RemoveEmptyEntries);
// Переменные для заголовков и содержимого
string headers = string.Empty;
string body = string.Empty;
bool headersEnd = false;
foreach (string piece in headersAndBody)
{
// Если заголовки ещё не закончились и текущая часть начинается с 'HTTP/' (независимо от регистра)
if (!headersEnd && piece.StartsWith("HTTP/", StringComparison.OrdinalIgnoreCase))
{
// Это ещё заголовки
headers += separator[0] + piece;
}
else
{
// Это уже содержимое
body += separator[0] + piece;
headersEnd = true;
}
}
// Избавляемся от пробелов и переводов строк в начале и конце заголовков и содержимого
headers = headers.Trim();
body = body.Trim();
// Записываем результаты (заголовки и содержимое по отдельности) в переменные проекта
project.Variables["splitted_headers"].Value = headers;
project.Variables["splitted_body"].Value = body;
Потом идёт кубик C# который парсит тело ответа на разные условия и в зависимости от найденного условия делает запись в нужный фаил
пример условий:
{ "<title>Access denied</title>", "Access-denied.txt" },
{ "<title>Request Rejected</title>", "Access-denied.txt" },
{ "<h1>Not Found</h1>", "Not-Found.txt" },
{ "<title>404 Not Found</title>", "Not-Found.txt" },
{ "<title>Domain Suspension</title>", "Domain-Expired.txt" },
{ "<title>Account Suspended</title>", "Domain-Expired.txt" },
если ничего не спарсилось то тогда происходит запись в фаил Unknown.txt
всё бы ничего но тут какая то ошибка, потому что зенка пишет:
Выполнение действия CSharp OwnCode: Parsing All stuff. Процесс не может получить доступ к файлу "E:\BASE\(другой софт)\BadUrlsSorter\files\output\Unknown.txt", так как этот файл используется другим процессом.
Из чего я делаю вывод что некоторые строки не записываются, хотя сам процесс идёт довольно бодро и все фаилы наполняються визуально достаточно быстро. Я запускаю этот проект в 200 потоков и вижу как иногда лезут ошибки.
C#:
string outputDirectory = Path.Combine(project.Directory, "files", "output");
Dictionary<string, string> searchStringToFileMap = new Dictionary<string, string>()
{
{ "<title>Access denied</title>", "Access-denied.txt" },
{ "<title>Request Rejected</title>", "Access-denied.txt" },
{ "<title>Connection denied by Geolocation</title>", "Access-denied.txt" },
// Добавьте другие строки поиска и файлы для записи результатов здесь...
};
bool matchFound = false;
string splittedBody = project.Variables["splitted_body"].Value;
if (!string.IsNullOrEmpty(splittedBody))
{
string[] lines = splittedBody.Split(new string[] { "\n", "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
HashSet<string> searchStrings = new HashSet<string>(searchStringToFileMap.Keys);
foreach (string line in lines)
{
foreach (string searchString in searchStrings)
{
if (line.Contains(searchString))
{
string fileName = searchStringToFileMap[searchString];
string filePath = Path.Combine(outputDirectory, fileName);
// Блокируем доступ к файлу с использованием lock для безопасной записи
lock (project) // Можно использовать любой объект для блокировки, например, project
{
File.AppendAllText(filePath, project.Variables["inputLink"].Value + Environment.NewLine);
}
matchFound = true;
break;
}
}
if (matchFound)
{
break;
}
}
}
if (!matchFound)
{
string defaultFilePath = Path.Combine(outputDirectory, "Unknown.txt");
File.AppendAllText(defaultFilePath, project.Variables["inputLink"].Value + Environment.NewLine);
}
Я пытался всё это время исправить этот код в chatgpt но он упорно подсовывает мне один и тот же код либо иногда пишет код который я так понимаю надо записывать там где записываются директивы using, я с этим ещё не работал и не разбирался, для меня это очень сложно.
Из сложившейся ситуации я сделал вывод что строки теряются потому что на запись тоже нужно делать lock. Я никогда не работал с этим, могу что то не так интерпритировать, но с chatgpt это не вывозит, помогите плиз кто чем может.