Как сделать, чтобы этот код работал правильно в многопотоке?

Светлана11422

Новичок
Регистрация
04.07.2019
Сообщения
19
Благодарностей
2
Баллы
3
Здравствуйте! Если не затруднит, могли бы вы подсказать, как сделать, чтобы сохранение в файл работало правильно в многопотоке?
Есть такой код:

C#:
lock(CommonCode.SyncObject)
{
    CommonCode.Parsing P = new CommonCode.Parsing(project.Variables["GetRespond"].Value, project.Variables["url"].Value, CommonCode.SRC, false, project.Lists["DoubleDomains_list"], project.Lists["Empty_list"]);
    
    //собираю результат
    StringBuilder sb = new StringBuilder();

    //результат:

    sb.Append(String.Format("\r\n\r\n", P.Internal_list.Count));
    foreach(string ss in P.Internal_list) sb.Append(ss + "\r\n");
    
lock (SyncObjects.ListSyncer){
    File.AppendAllText(project.Directory + @"\Test.txt", sb.ToString(), Encoding.UTF8);
}
    
}
Взят этот кусок кода из конкурсной статьи тут:

Мне нужно, чтобы сохранение в файл работало в многопотоке, в 1 поток всё верно сохраняет, а вот в несколько уже не выходит.
Пробовала лочить так:

C#:
lock (SyncObjects.ListSyncer){
    File.AppendAllText(project.Directory + @"\Test.txt", sb.ToString(), Encoding.UTF8);
}
Но не помогает.
Может быть нужно использовать другой метод для сохранения данных в файл? А не такой: File.AppendAllText
Или как сделать, чтобы сначала в переменную, а потом в список сохранять?
Может таким образом будет верно работать в многопотоке.

Ещё только разбираюсь, поэтому не судите строго O:)
 

ssXXXss

Client
Регистрация
23.12.2014
Сообщения
7 379
Благодарностей
2 039
Баллы
113
а зачем вообще лочить сохранение в файл, проверки на дубли нет, сохраняй без лока и все записи увидишь
 

Mikhail B.

Moderator
Регистрация
23.12.2014
Сообщения
14 328
Благодарностей
5 431
Баллы
113
Сколько потоков запускаете?
 
  • Спасибо
Реакции: Светлана11422

ssXXXss

Client
Регистрация
23.12.2014
Сообщения
7 379
Благодарностей
2 039
Баллы
113
но при записи не вздумай открывать и проверять простым текстовым редактором, если им открываешь при записи то потеряшь записи
 
  • Спасибо
Реакции: Светлана11422

Mikhail B.

Moderator
Регистрация
23.12.2014
Сообщения
14 328
Благодарностей
5 431
Баллы
113
  • Спасибо
Реакции: Светлана11422

ssXXXss

Client
Регистрация
23.12.2014
Сообщения
7 379
Благодарностей
2 039
Баллы
113
  • Спасибо
Реакции: Светлана11422

Mikhail B.

Moderator
Регистрация
23.12.2014
Сообщения
14 328
Благодарностей
5 431
Баллы
113

Светлана11422

Новичок
Регистрация
04.07.2019
Сообщения
19
Благодарностей
2
Баллы
3
Сколько потоков запускаете?
В 5-10 потоков тестирую


а зачем вообще лочить сохранение в файл, проверки на дубли нет, сохраняй без лока и все записи увидишь
Почему-то в 1 поток сохраняет все записи, а допустим в 5 сохраняет одну-две, хотя должно быть 5.
Поэтому и не понимаю, как лучше сделать

но при записи не вздумай открывать и проверять простым текстовым редактором, если им открываешь при записи то потеряшь записи
Файл не трогаю


Получается мне нужно лок убрать совсем? До этого не было и всё равно как-то не правильно сохраняло файл
 

ssXXXss

Client
Регистрация
23.12.2014
Сообщения
7 379
Благодарностей
2 039
Баллы
113
Я не разбираюсь в шарпе просто. А как должно быть?
у меня ничего не запущено, но я бы это StringBuilder вынес из лока, и записывал бы ндругим методом в файл, тоже зеновским и при чём он проверен и шустро записывает, покрайне мере в моих проектах не было промахов при записи, тем более тут многопоток всего а не паралель
 
  • Спасибо
Реакции: Светлана11422

Светлана11422

Новичок
Регистрация
04.07.2019
Сообщения
19
Благодарностей
2
Баллы
3
у меня ничего не запущено, но я бы это StringBuilder вынес из лока, и записывал бы ндругим методом в файл, тоже зеновским и при чём он проверен и шустро записывает, покрайне мере в моих проектах не было промахов при записи, тем более тут многопоток всего а не паралель
Каким методом порекомендуете записывать в файл?
 

ssXXXss

Client
Регистрация
23.12.2014
Сообщения
7 379
Благодарностей
2 039
Баллы
113
File.AppendAllText если правильно помню то он блокирует файл при записи, а второй поток выходит по ошибке так как файл для записи ему не доступен, а лок в многопотоке таким методом не спасёт
 

ssXXXss

Client
Регистрация
23.12.2014
Сообщения
7 379
Благодарностей
2 039
Баллы
113
есть новей статья как брошеные домены собирать, но это уже лажа, фиг их зарегаешь в большинстве, ну может кто заниманься этим то умеет это делать, а так вот это попробуй сохранять, но и вынеси из лока FileSystem.FileAppendString(project.Directory + @"\Test.txt", sb.ToString(), true);
 
  • Спасибо
Реакции: Светлана11422

Светлана11422

Новичок
Регистрация
04.07.2019
Сообщения
19
Благодарностей
2
Баллы
3
есть новей статья как брошеные домены собирать, но это уже лажа, фиг их зарегаешь в большинстве, ну может кто заниманься этим то умеет это делать, а так вот это попробуй сохранять, но и вынеси из лока FileSystem.FileAppendString(project.Directory + @"\Test.txt", sb.ToString(), true);
Спасибо, попробую.
 

ssXXXss

Client
Регистрация
23.12.2014
Сообщения
7 379
Благодарностей
2 039
Баллы
113
и вообще для чего лок если это не паралель и не сохранение в привязаный список ? просто я сам уже с пол года не залазил в зенку, уже забывать стал ))
 

ssXXXss

Client
Регистрация
23.12.2014
Сообщения
7 379
Благодарностей
2 039
Баллы
113
попробуй так

C#:
CommonCode.Parsing P = new CommonCode.Parsing(project.Variables["GetRespond"].Value, project.Variables["url"].Value, CommonCode.SRC, false, project.Lists["DoubleDomains_list"], project.Lists["Empty_list"]);

//собираю результат
StringBuilder sb = new StringBuilder();

//результат:
sb.Append(String.Format("\r\n\r\n", P.Internal_list.Count));

foreach(string ss in P.Internal_list) sb.Append(ss + "\r\n");
FileSystem.FileAppendString(project.Directory + @"\Test.txt", sb.ToString(), true);
 
Последнее редактирование:
  • Спасибо
Реакции: Светлана11422

ssXXXss

Client
Регистрация
23.12.2014
Сообщения
7 379
Благодарностей
2 039
Баллы
113
а как сейчас код оформить на форуме, извините что тут пишу
 

samsonnn

Client
Регистрация
02.06.2015
Сообщения
1 657
Благодарностей
1 325
Баллы
113
  • Спасибо
Реакции: ssXXXss

ssXXXss

Client
Регистрация
23.12.2014
Сообщения
7 379
Благодарностей
2 039
Баллы
113

Светлана11422

Новичок
Регистрация
04.07.2019
Сообщения
19
Благодарностей
2
Баллы
3
попробуй так

C#:
CommonCode.Parsing P = new CommonCode.Parsing(project.Variables["GetRespond"].Value, project.Variables["url"].Value, CommonCode.SRC, false, project.Lists["DoubleDomains_list"], project.Lists["Empty_list"]);

//собираю результат
StringBuilder sb = new StringBuilder();

//результат:
sb.Append(String.Format("\r\n\r\n", P.Internal_list.Count));

foreach(string ss in P.Internal_list) sb.Append(ss + "\r\n");
FileSystem.FileAppendString(project.Directory + @"\Test.txt", sb.ToString(), true);
А как сделать, чтобы сохраняло в список в проекте не привязанный?
Чтобы не создавал этот файл в директории проекта, а просто сохранял в список
 

ssXXXss

Client
Регистрация
23.12.2014
Сообщения
7 379
Благодарностей
2 039
Баллы
113
А как сделать, чтобы сохраняло в список в проекте не привязанный?
Чтобы не создавал этот файл в директории проекта, а просто сохранял в список
он не создаёт, он имено пишет в тот файл в который укажещь

P.S.. и да, там вроде всё таки нужен лок при обработке посмотрев сейас код , но не при записи
 

Светлана11422

Новичок
Регистрация
04.07.2019
Сообщения
19
Благодарностей
2
Баллы
3
он не создаёт, он имено пишет в тот файл в который укажещь

P.S.. и да, там вроде всё таки нужен лок при обработке посмотрев сейас код , но не при записи
Сейчас пробую, у меня создаёт этот файл в директории. Удаляю полностью файл, но этот код создаёт заново

C#:
FileSystem.FileAppendString(project.Directory + @"\Test.txt", sb.ToString(), true);
А как можно сделать, чтобы просто писалось в список в проекте? Без сохранения в текстовый файл
 

ssXXXss

Client
Регистрация
23.12.2014
Сообщения
7 379
Благодарностей
2 039
Баллы
113
Сейчас пробую, у меня создаёт этот файл в директории. Удаляю полностью файл, но этот код создаёт заново

C#:
FileSystem.FileAppendString(project.Directory + @"\Test.txt", sb.ToString(), true);
А как можно сделать, чтобы просто писалось в список в проекте? Без сохранения в текстовый файл
я уже всё позабыл )) чайник ))
 

ssXXXss

Client
Регистрация
23.12.2014
Сообщения
7 379
Благодарностей
2 039
Баллы
113
да вроде вспомнил что файл создаёт этот код, но если файл создан то он не пересоздаёт и не перезаписывает, так что один раз его можно вручную создать, чтобы не было бага между потоками что каждый начнёт его создавать, ну или поставить проверку на существование файла, но если это многопоток и долгий процес нахер такое делать, проверка замедляет проект, иногда надо и ручками проекту помочь для облегчения, ну или пусть каждый поток пишет в свой файл
 
  • Спасибо
Реакции: Светлана11422

ssXXXss

Client
Регистрация
23.12.2014
Сообщения
7 379
Благодарностей
2 039
Баллы
113
Сейчас пробую, у меня создаёт этот файл в директории. Удаляю полностью файл, но этот код создаёт заново

C#:
FileSystem.FileAppendString(project.Directory + @"\Test.txt", sb.ToString(), true);
А как можно сделать, чтобы просто писалось в список в проекте? Без сохранения в текстовый файл
привязывай списоа, ставь лок, но если список раздувается прилично то не советую этлт метод
 

Светлана11422

Новичок
Регистрация
04.07.2019
Сообщения
19
Благодарностей
2
Баллы
3
Здравствуйте! Так и не удалось мне настроить многопоточную работу, возможно кто-нибудь ещё даст какие-то рекомендации, как сделать чтобы работало верно в многопотоке?

Сейчас пробую вообще не использовать список, просто складывать результат в переменную:

C#:
lock(CommonCode.SyncObject)
{
CommonCode.Parsing P = new CommonCode.Parsing(project.Variables["GetRespond"].Value, project.Variables["url"].Value, CommonCode.SRC, false, project.Lists["DoubleDomains_list"], project.Lists["Empty_list"]);

//собираю результат
StringBuilder sb = new StringBuilder();

//результат:
var  res = sb.Append(String.Format("\r\n\r\n", P.Internal_list.Count));

foreach(string ss in P.Internal_list) sb.Append(ss + "\r\n");

return res;
}
В 1 поток проблем нет, всё работает, а вот в несколько потоков одновременно отрабатывает только один верно.
Вероятно этот lock не работает или что может быть?

В общем коде CommonCode так прописано:

C#:
/// <summary>
    /// A simple class of the common code
    /// </summary>
    public class CommonCode
    {
        /// <summary>
        /// Lock this object to mark part of code for single thread execution
        /// </summary>
        public static object SyncObject = new object();
        
        public static object ListSyncer = new object();
        
        //Объект списка
        public static object FileLocker = new object();
 

ssXXXss

Client
Регистрация
23.12.2014
Сообщения
7 379
Благодарностей
2 039
Баллы
113
CommonCode.SRC
это к чему относится ?
 

ssXXXss

Client
Регистрация
23.12.2014
Сообщения
7 379
Благодарностей
2 039
Баллы
113
Здравствуйте! Так и не удалось мне настроить многопоточную работу, возможно кто-нибудь ещё даст какие-то рекомендации, как сделать чтобы работало верно в многопотоке?

Сейчас пробую вообще не использовать список, просто складывать результат в переменную:

C#:
lock(CommonCode.SyncObject)
{
CommonCode.Parsing P = new CommonCode.Parsing(project.Variables["GetRespond"].Value, project.Variables["url"].Value, CommonCode.SRC, false, project.Lists["DoubleDomains_list"], project.Lists["Empty_list"]);

//собираю результат
StringBuilder sb = new StringBuilder();

//результат:
var  res = sb.Append(String.Format("\r\n\r\n", P.Internal_list.Count));

foreach(string ss in P.Internal_list) sb.Append(ss + "\r\n");

return res;
}
В 1 поток проблем нет, всё работает, а вот в несколько потоков одновременно отрабатывает только один верно.
Вероятно этот lock не работает или что может быть?
вообще не пойму что ты тут нахимичила в этом куске кода в строках с 9 по 13,
 

GraaFf

Client
Регистрация
21.05.2016
Сообщения
126
Благодарностей
53
Баллы
28
Здравствуйте! Так и не удалось мне настроить многопоточную работу, возможно кто-нибудь ещё даст какие-то рекомендации, как сделать чтобы работало верно в многопотоке?

Сейчас пробую вообще не использовать список, просто складывать результат в переменную:

C#:
lock(CommonCode.SyncObject)
{
CommonCode.Parsing P = new CommonCode.Parsing(project.Variables["GetRespond"].Value, project.Variables["url"].Value, CommonCode.SRC, false, project.Lists["DoubleDomains_list"], project.Lists["Empty_list"]);

//собираю результат
StringBuilder sb = new StringBuilder();

//результат:
var  res = sb.Append(String.Format("\r\n\r\n", P.Internal_list.Count));

foreach(string ss in P.Internal_list) sb.Append(ss + "\r\n");

return res;
}
В 1 поток проблем нет, всё работает, а вот в несколько потоков одновременно отрабатывает только один верно.
Вероятно этот lock не работает или что может быть?

В общем коде CommonCode так прописано:

C#:
/// <summary>
    /// A simple class of the common code
    /// </summary>
    public class CommonCode
    {
        /// <summary>
        /// Lock this object to mark part of code for single thread execution
        /// </summary>
        public static object SyncObject = new object();
        
        public static object ListSyncer = new object();
        
        //Объект списка
        public static object FileLocker = new object();
Что в логе выдает?
 

Светлана11422

Новичок
Регистрация
04.07.2019
Сообщения
19
Благодарностей
2
Баллы
3
CommonCode.SRC
это к чему относится ?
Этот кусок кода не трогался, взят был как есть с того шаблона, я точно не знаю к чему это относится.
Чтобы было понятнее, прикладываю сам проект.

Мне нужно чтобы в многопотоке работало и складывало в переменную или список для дальнейшей работы, в 1 поток работает, потестируйте, а вот в несколько не даёт.
Там сделано для теста, чтобы видеть в логе, какие страницы берутся
 

Вложения

ssXXXss

Client
Регистрация
23.12.2014
Сообщения
7 379
Благодарностей
2 039
Баллы
113
Этот кусок кода не трогался, взят был как есть с того шаблона, я точно не знаю к чему это относится.
Чтобы было понятнее, прикладываю сам проект.

Мне нужно чтобы в многопотоке работало и складывало в переменную или список для дальнейшей работы, в 1 поток работает, потестируйте, а вот в несколько не даёт.
Там сделано для теста, чтобы видеть в логе, какие страницы берутся
так а куда всё это должно сохраняться ?
 

Кто просматривает тему: (Всего: 1, Пользователи: 0, Гости: 1)