powered by simpleCommunicator - 2.0.56     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Как написать корректно такой кусок, чтобы GC ничего лишнего не выкинул?
10 сообщений из 10, страница 1 из 1
Как написать корректно такой кусок, чтобы GC ничего лишнего не выкинул?
    #38433389
Charles Weyland
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
По некоторому событию (при обнаружении новых файлов в папке) читаю новые файлы, и последовательно по одному как-то обрабатываю и удаляю.

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
            var files = Directory.GetFiles(inbox);
            foreach (var file in files)
            {
                thread = new Thread(ЧитатьИОбратботатьФайл);
                thread.Start(file);
                thread = new Thread(DelFile);
                thread.Start(file);
                Console.WriteLine("----------------------------------------------");
            }


Обе функции ("ЧитатьИОбратботатьФайл" и "DelFile") построены по одинаковому принципу:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
        private void DelFile(object file)
        {
            bool success = false;
            Console.WriteLine("Удаление: " + file.ToString());
            while (!success) //вечный цикл, пока не удалится
            {
                try
                {
                    File.Delete(file.ToString());
                    success = true;
                }
                catch (Exception e)
                {
                }
            }
        }



Что не нравится: GC удаляет все объекты, на которые никто не ссылается. То есть, конкретно вот эта часть неправильная:
Код: c#
1.
2.
3.
4.
                thread = new Thread(ЧитатьИОбратботатьФайл);
                thread.Start(file);
                thread = new Thread(DelFile);
                thread.Start(file);


Но логика в этом фрагменте такая: запустить функцию в отдельном потоке, а, как только она выполнится, забить на неё и на созданный объект "new Thread(DelFile)"
...
Рейтинг: 0 / 0
Как написать корректно такой кусок, чтобы GC ничего лишнего не выкинул?
    #38433406
beg-in-er
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Charles Weyland,

не поможет ли System.Threading.ThreadPool ?

а можно мозг момыть GC - создать List<object> куда подпихивать создаваемые потоки.
уж больно иногда тормозит ThreadPool
...
Рейтинг: 0 / 0
Как написать корректно такой кусок, чтобы GC ничего лишнего не выкинул?
    #38433905
Charles Weyland
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
beg-in-erCharles Weyland,

не поможет ли System.Threading.ThreadPool ?

а можно мозг момыть GC - создать List<object> куда подпихивать создаваемые потоки.
уж больно иногда тормозит ThreadPool
я думал над этим, но надо будет создавать собственный класс, который отслеживает, закончил ли thread выполняться, если да, то удалять его из списка.
Кстати, после выполнения объект сохраняется, или выгружается из памяти?
т.е. что происходит с объектом "new Thread(DelFile)" после того, как DelFile закончит своё выполнение?
...
Рейтинг: 0 / 0
Как написать корректно такой кусок, чтобы GC ничего лишнего не выкинул?
    #38433955
Фотография Где-то в степи
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Charles Weyland,
ну GC может и никогда не вызваться, и зачем вам это надо?
Объясните мотивацию что Вы создали
автор thread = new Thread(ЧитатьИОбратботатьФайл);
thread.Start(file);
запустили поток на выполнение, обработка файла.
потом
авторthread = new Thread(DelFile);
thread.Start(file);
инициировали переменную другим объектом, потеряли всякую связь с первым объектом,
запустили поток удаления.
крутится два потока, один работает с файлом другой в это время пытается его удалить, ну естественно файл занят -
ексепшен, ловим его и в бесконечном цикле пытаемся его опять удалить - жуть...
хотя по хорошему можно обойтись одним потоком
с одной процедурой
Код: c#
1.
2.
3.
4.
5.
Void Foo(string filename)
{
ЧитатьИОбратботатьФайл(filename);
DelFile(filename)
}


и вообще зачем создавать потоки, если они и так созданы
Код: c#
1.
2.
3.
4.
5.
6.
7.
 Action<string> action=  s => {  DelFile(s);  ЧитатьИОбратботатьФайл(s); };
 var files = Directory.GetFiles(inbox);
  foreach (var file in files)
 {
    action(file);
    Console.WriteLine("----------------------------------------------");
 }


???
...
Рейтинг: 0 / 0
Как написать корректно такой кусок, чтобы GC ничего лишнего не выкинул?
    #38433971
Фотография Где-то в степи
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Где-то в степи,
action(file); ->ThreadPool.QueueUserWorkItem(action, file);
...
Рейтинг: 0 / 0
Как написать корректно такой кусок, чтобы GC ничего лишнего не выкинул?
    #38434090
bazile
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Charles Weyland, тебе уже посоветовали решение - удаляй файл в конце функции обработки. Ее код можно записать примерно так:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
private void ProcessFile(string filePath)
{
	try
	{
		using (var reader = new StreamReader(filePath))
		{
			...
		}
	}
	finally
	{
		File.Delete(filePath);
	}
}



По поводу твоей функции DelFile. Во-первых, никогда не пиши поток с проверкой в "бесконечном" цикле. Это нагружает процессор ненужной работой. Для интереса посмотри на нагрузку процессора во время работы своей программы. В подобных ситуациях надо искать способ организовать ожидание нужного события через примитивы синронизации: lock, WaitHandle, семафоры и т.п. Во-вторых, генерация исключений в "бесконечном" цикле тоже наверняка ухуждает производительность программы. Ведь обработка исключений тоже имеет свою цену. А твой код генерирует их пачками. В общем не пиши больше такой код.

Charles WeylandЧто не нравится: GC удаляет все объекты, на которые никто не ссылается.
В этом и состоит его работа так что непонятно что может здесь не нравится. Раз на объект никто не ссылается значит он уже больше не нужен.

Charles WeylandКстати, после выполнения объект сохраняется, или выгружается из памяти?
т.е. что происходит с объектом "new Thread(DelFile)" после того, как DelFile закончит своё выполнение?
Сборщик мусора относится к экземплярам Thread точно также как к экземплярам других типов. Если значение переменной никому не нужно, то оно может быть удалено из кучи еще до завершения потока. Не надо путать экземпляр типа Thread с самим потоком. Первый это "всего лишь" обертка над API функциями ОС. Поток, как объект ОС, живет независимо от класса Thread т.к. не имеет понятия о его существовании.
...
Рейтинг: 0 / 0
Как написать корректно такой кусок, чтобы GC ничего лишнего не выкинул?
    #38434262
Charles Weyland
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
я согласен с замечанием, здесь у меня ошибка приницииальная
Charles Weyland
Код: c#
1.
2.
3.
4.
                thread = new Thread(ЧитатьИОбратботатьФайл);
                thread.Start(file);
                thread = new Thread(DelFile);
                thread.Start(file);


всё в один поток надо оформить. Но вопрос от этого не меняется))
...
Рейтинг: 0 / 0
Как написать корректно такой кусок, чтобы GC ничего лишнего не выкинул?
    #38434271
bazile
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Charles WeylandНо вопрос от этого не меняется))
Вопрос о сборщике мусора? А почему ты решил что здесь есть какая-то проблема с ним?
...
Рейтинг: 0 / 0
Как написать корректно такой кусок, чтобы GC ничего лишнего не выкинул?
    #38434538
Charles Weyland
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Где-то в степии вообще зачем создавать потоки, если они и так созданы
Код: c#
1.
2.
3.
4.
5.
6.
7.
 Action<string> action=  s => {  DelFile(s);  ЧитатьИОбратботатьФайл(s); };
 var files = Directory.GetFiles(inbox);
  foreach (var file in files)
 {
    action(file);
    Console.WriteLine("----------------------------------------------");
 }


ооо, и что, "DelFile(s); ЧитатьИОбратботатьФайл(s);" выполнится в отдельном потоке??
Это ж то, что мне нужно!... спасибо!!)))
...
Рейтинг: 0 / 0
Как написать корректно такой кусок, чтобы GC ничего лишнего не выкинул?
    #38434552
bazile
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Charles Weylandооо, и что, "DelFile(s); ЧитатьИОбратботатьФайл(s);" выполнится в отдельном потоке??
В таком виде (action(file)) выполнение пойдет в том же потоке. Нужно самому создавать поток или использовать ThreadPool как "Где-то в степи" написал. Использование лямбды дает преимущества строгой типизации для аргумента.
...
Рейтинг: 0 / 0
10 сообщений из 10, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Как написать корректно такой кусок, чтобы GC ничего лишнего не выкинул?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]