Логирование при использовании многопоточности04.09.2018, 16:12. Показов 5110. Ответов 26
Метки нет (Все метки)
Добрый день.
Программа качает файлы из списка адресов. Делает это асинхронно. О результате пишет в лог-файл. При запуске программы постоянно вылетает эксепшен о недоступности файла, поскольку он используется другим процессом. Хотелось бы понять почему. Я предполагаю, что каждый таск пытается создать новый объект StreamWriter в своем потоке - из-за этого другие потоки теряют возможность этот файл использовать. Вопрос: 1. Верно ли я понял причину? 2. Как заставить таски создавать объект StreamWriter всякий раз в одном и том же потоке? 3. Не будет ли у них опять взаимной блокировки и как ее избежать? Код:
0
|
||||||
| 04.09.2018, 16:12 | |
|
Ответы с готовыми решениями:
26
Программа вычисления выражения работает некорректно при использовании многопоточности Зависает при многопоточности File.OpenRead при многопоточности |
|
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
|
|||||
| 04.09.2018, 16:24 | |||||
|
В классе-логгере создавайте поток при инициализации объекта, а не при каждой записи. В методе логирования делайте замыкание и пишите в уже открытый поток. Если не добавить, то в файле с логом будет чепуха, а не логи. Если хотите минимизировать взаимную блокировку (но не устранить полностью), то в методе логгирования пишите не сразу в файл, а просто добавляйте строк лога в какую-нибудь очередь, а отдельным потоком записывайте элементы из очереди уже в файл.
0
|
|||||
|
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
|
||||||||
| 04.09.2018, 16:53 | ||||||||
0
|
||||||||
| 04.09.2018, 17:11 [ТС] | ||
|
Кину себе пару ссылочек для дальнейшего прочтения - может еще кому пригодится: Lazy - https://metanit.com/sharp/tutorial/20.1.php Синглтон - https://metanit.com/sharp/patterns/2.3.php IDisposable - https://habr.com/post/89720/
0
|
||
|
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
|
|||||||||||
| 04.09.2018, 17:30 | |||||||||||
|
skitale, примерная реализация через синглтон:
Экземпляр логгера получается через обращение к свойству Instance:
0
|
|||||||||||
| 04.09.2018, 17:52 [ТС] | |||
|
Больше похоже на делегат, но нет слова "delegate". Я чет запутался ![]() Добавлено через 1 минуту
0
|
|||
|
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
|
||||||||
| 04.09.2018, 17:56 | ||||||||
0
|
||||||||
|
4694 / 2702 / 734
Регистрация: 02.08.2011
Сообщений: 7,233
|
||||||
| 04.09.2018, 18:07 | ||||||
|
kolorotur, интересует одна деталь - а нужно ли в данном случае вбрасывать в методе Write ObjectDisposedException? Типа того:
0
|
||||||
|
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
|
|
| 04.09.2018, 19:15 | |
|
0
|
|
| 05.09.2018, 11:39 [ТС] | ||
|
И по сути дела это же получается булевый флаг - почему тогда он определен как тип object?
0
|
||
|
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
|
|||||
| 05.09.2018, 12:04 | |||||
|
"Кто-то" в данном случае — другие потоки. Одновременно блок lock может выполнять только один поток, все остальные будут заморожены до окончания выполнения этого блока. Поэтому лочить нужно исключительно тот код, который затрагивает общие ресурсы, при этом желательно чтобы этот код выполнялся как можно быстрее — чтобы остальные потоки меньше ждали. Как это не имеет? Он используется для синхронизации. Отсюда и приватное поле sync. Булевый флаг — значимый тип, он не подходит.
1
|
|||||
|
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
|
||
| 05.09.2018, 15:07 | ||
await Task.WhenAll(taskList);
0
|
||
| 05.09.2018, 16:00 [ТС] | |||||||
|
Вот полный код:
Что-то никак в голове не уложится как работает это await/async. Как выполнить завершение программы только когда WaitAll() завершится? Прошу прощения за глупые вопросы... Но я что-то совсем затупил...
0
|
|||||||
|
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
|
||||||||
| 05.09.2018, 16:18 | ||||||||
|
Если у вас метод асинхронный, то возвращайте Task, если логически он void; и Task<T>, если он возвращает T. Рефакторинг:
Ставьте минимум 7.1 — там можно.
0
|
||||||||
| 05.09.2018, 17:31 [ТС] | |||||||||||||||||||||
|
kolorotur, во-первых большое спасибо за ваши ответы - мне это очень помогает, а во-вторых есть несколько вопросов:
Кусок кода, который вызвал вопросы:
Почему не возвращаем просто тип List<Task>? Почему именно IEnumerable<Task>? В чем будет разница если мы вызовем только этот интерфейс?
Немного дурной вопрос, наверное, но все же: во всех ли случаях в C# будет правомерна такая операция? Всегда ли выражение, передаваемое в качестве параметра будет вычисляться?
Здесь мы не создаем Task в коде потому что он как бы автоматом создается самим методом? Но почему нет return?
0
|
|||||||||||||||||||||
|
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
|
|||||
| 05.09.2018, 17:38 | |||||
|
Личная привычка использовать минимально необходимые для работы типы: если мне не нужен функционал списка, а нужно просто перечислять элементы, то IEnumerable вполне хватает. Меньше лишних связей получается. Наличие этих слов — указание компилятору развернуть метод в полноценную асинхронную модель и возвращать из него правильный таск. Если убрать из сигнатуры async, а из тела await, то придется возвращать таск. Если изменить возвращаемый тип на Task<T>, то где-то придется возвращать экземпляр Т. Ну а поскольку логически метод void и в сигнатуре прописан async, явно возвращать ничего не надо. Более того, это будет ошибкой компиляции.
0
|
|||||
| 05.09.2018, 17:59 [ТС] | ||||||||
Проехали.Еще момент: Чем обусловлено использование var вместо явного List<Task>? По сути-то там должно быть IEnumerable<Task>?
0
|
||||||||
|
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
|
||||
| 05.09.2018, 18:04 | ||||
![]() Добавлено через 1 минуту Поясните, пожалуйста.
0
|
||||
| 05.09.2018, 18:04 | |
|
Помогаю со студенческими работами здесь
20
Ошибка при реализации многопоточности
Работа статического метода при многопоточности? Странные символы при выводе в файл при использовании BinaryWriter Как правильно передать объект в функцию при использовании многопоточности Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие.
Ссылка в Linux — это дополнительная запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая. . .
|
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ВВЕДЕНИЕ
Выполняя задание на управление насосной группой заполнения резервуара,. . .
|
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
|
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога
Финальные проекты на Си и на C++:
hello-sdl3-c. zip
hello-sdl3-cpp. zip
Результат:
|
|
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога
MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
|
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд.
Даже если у вас. . .
|
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает
монорепозиторий в котором находятся все исходники.
При создании нового решения, мы просто добавляем нужные проекты
и имеем. . .
|
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение:
В этой книге («Подход, основанный на вариантах использования») Ивар утверждает,
что архитектура программного обеспечения — это
структуры,. . .
|