C # - Перемещение файлов - в очередь или многопоточность - PullRequest
4 голосов
/ 04 декабря 2009

У меня есть приложение, которое перемещает проект и его файлы из предварительного просмотра в производство, используя интерфейс Flex и веб-сервис .NET. В настоящее время процесс занимает около 5-10 минут / на проект. Помимо проблем с задержкой, это действительно не должно занимать так много времени. Мне интересно, является ли это хорошим вариантом использования для многопоточности. Кроме того, если учесть, что пользователь может захотеть запустить несколько проектов или один за другим, есть ли способ поставить в очередь задания.

Любые предложения и примеры с благодарностью.

Спасибо!

Ответы [ 8 ]

4 голосов
/ 04 декабря 2009

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

2 голосов
/ 04 декабря 2009

Как примечание - независимо от того, решите ли вы ставить в очередь задания, вы будете использовать многопоточность. Организация очереди - это всего лишь один из способов решения того, что в конечном итоге решается с помощью многопоточности.

И да, я бы порекомендовал вам создать очередь для каждого проекта.

1 голос
/ 04 декабря 2009

Вы должны сравнить скорость вашего кода по сравнению с простым копированием в Windows (т. Е. С помощью проводника или командной строки) по сравнению с копированием с помощью чего-то более продвинутого, например TeraCopy . Если ваш код значительно медленнее, чем Window, посмотрите на части кода для оптимизации с помощью профилировщика. Если ваш код примерно такой же быстрый, как Windows, но медленнее, чем TeraCopy, тогда многопоточность может помочь.

Многопоточность обычно не помогает, когда операции ввода-вывода связаны, но копирование файлов включает чтение с диска и запись по сети. Это две операции ввода / вывода, поэтому если вы разделите их на разные потоки, это может повысить производительность. Для чего-то подобного вам нужна настройка производителя / потребителя, где у вас есть Круговая очередь с одним потоком, читающим с диска и записывающим в очередь, и другим потоком, читающим из очереди и записывающим в сеть. Важно помнить, что два потока не будут работать с одинаковой скоростью, поэтому, если очередь заполнится, подождите, прежде чем записывать больше данных, и, если она пуста, подождите, прежде чем записать. Также стратегия блокировки может иметь большое влияние на производительность и может привести к снижению производительности до более медленной, чем однопоточная реализация.

0 голосов
/ 05 декабря 2009

Самое первое, что вы должны сделать, - это направить любой инструмент профилирования на ваше программное обеспечение. Если вы не можете этого сделать (например, если у вас нет такого инструмента), введите код регистрации.

Самое первое, что вам нужно сделать, это выяснить , что занимает много времени для завершения, а затем почему это занимает много времени, чтобы завершить. То, что ваша операция «копирования» в целом занимает много времени, не достаточно хороша, вам нужно точно определить причину этого до метода или набора методов.

Пока вы этого не сделаете, все остальные вещи, которые вы можете сделать с вашим кодом, скорее всего, будут догадываться. Мой опыт научил меня, что когда дело доходит до производительности, 9 из 10 причин замедления работы становятся сюрпризом для парней, которые написали код.

Итак, сначала измерьте, а затем измените.

Например, вы можете обнаружить, что на самом деле вы сообщаете о ходе копирования файла на байтовой основе в графический интерфейс, используя синхронный вызов пользовательского интерфейса, и в этом случае это не имеет значения насколько быстро может выполняться фактическое копирование, вы все равно будете зависеть от скорости обработки сообщений.

Но это только гипотеза, пока вы не знаете, поэтому сначала измерьте, а затем измените.

0 голосов
/ 05 декабря 2009

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

Недавно я написал статью о чтении / записи файлов с несколькими файлами на ddj.com.

См. http://www.ddj.com/go-parallel/article/showArticle.jhtml?articleID=220300055.

См. Также связанный вопрос Будет ли использование нескольких потоков с производительностью справки RandomAccessFile?

В частности, я понял, что при работе с очень большим количеством файлов IS хорошая идея использовать несколько потоков. Напротив, использование множества потоков во многих случаях не замедляет работу приложений так, как это обычно ожидается.

Сказав, что я бы сказал, нет другого способа выяснить это, кроме как попробовать все возможные разные подходы. Это зависит от многих условий: аппаратного обеспечения, ОС, драйверов и т. Д.

0 голосов
/ 05 декабря 2009

Согласны со всеми по поводу ограниченной производительности параллельного выполнения задач.

Если у вас есть полный контроль над средой развертывания, вы можете использовать Rhino Queues:

http://ayende.com/Blog/archive/2008/08/01/Rhino-Queues.aspx

Это позволит вам асинхронно создавать очередь заданий (например, из службы WCF, вызываемой из приложения Silverlight / Flex) и использовать их синхронно.

В качестве альтернативы вы можете использовать WCF и MSMQ, но кривая обучения выше.

0 голосов
/ 04 декабря 2009

Вы должны попробовать использовать ThreadPool.

ThreadPool.QueueUserWorkItem(MoveProject, project);
0 голосов
/ 04 декабря 2009

Если вы перемещаете вещи только между двумя компьютерами, сеть станет узким местом, поэтому вы можете поставить эти операции в очередь.

Аналогично, на той же машине ввод / вывод будет узким местом, поэтому вы тоже захотите стоять в очереди.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...