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

Код: 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
18.10.2013, 19:11
    #38433406
beg-in-er
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как написать корректно такой кусок, чтобы GC ничего лишнего не выкинул?
Charles Weyland,

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

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

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

а можно мозг момыть GC - создать List<object> куда подпихивать создаваемые потоки.
уж больно иногда тормозит ThreadPool
я думал над этим, но надо будет создавать собственный класс, который отслеживает, закончил ли thread выполняться, если да, то удалять его из списка.
Кстати, после выполнения объект сохраняется, или выгружается из памяти?
т.е. что происходит с объектом "new Thread(DelFile)" после того, как DelFile закончит своё выполнение?
...
Рейтинг: 0 / 0
19.10.2013, 15:35
    #38433955
Где-то в степи
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как написать корректно такой кусок, чтобы GC ничего лишнего не выкинул?
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
19.10.2013, 16:14
    #38433971
Где-то в степи
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как написать корректно такой кусок, чтобы GC ничего лишнего не выкинул?
Где-то в степи,
action(file); ->ThreadPool.QueueUserWorkItem(action, file);
...
Рейтинг: 0 / 0
19.10.2013, 19:31
    #38434090
bazile
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как написать корректно такой кусок, чтобы GC ничего лишнего не выкинул?
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
19.10.2013, 23:31
    #38434262
Charles Weyland
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как написать корректно такой кусок, чтобы GC ничего лишнего не выкинул?
я согласен с замечанием, здесь у меня ошибка приницииальная
Charles Weyland
Код: c#
1.
2.
3.
4.
                thread = new Thread(ЧитатьИОбратботатьФайл);
                thread.Start(file);
                thread = new Thread(DelFile);
                thread.Start(file);


всё в один поток надо оформить. Но вопрос от этого не меняется))
...
Рейтинг: 0 / 0
19.10.2013, 23:59
    #38434271
bazile
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как написать корректно такой кусок, чтобы GC ничего лишнего не выкинул?
Charles WeylandНо вопрос от этого не меняется))
Вопрос о сборщике мусора? А почему ты решил что здесь есть какая-то проблема с ним?
...
Рейтинг: 0 / 0
20.10.2013, 15:17
    #38434538
Charles Weyland
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как написать корректно такой кусок, чтобы GC ничего лишнего не выкинул?
Где-то в степии вообще зачем создавать потоки, если они и так созданы
Код: 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
20.10.2013, 15:36
    #38434552
bazile
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как написать корректно такой кусок, чтобы GC ничего лишнего не выкинул?
Charles Weylandооо, и что, "DelFile(s); ЧитатьИОбратботатьФайл(s);" выполнится в отдельном потоке??
В таком виде (action(file)) выполнение пойдет в том же потоке. Нужно самому создавать поток или использовать ThreadPool как "Где-то в степи" написал. Использование лямбды дает преимущества строгой типизации для аргумента.
...
Рейтинг: 0 / 0
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Как написать корректно такой кусок, чтобы GC ничего лишнего не выкинул? / 10 сообщений из 10, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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