Параллельное программирование в C#

Я интересуюсь приобретением знаний о параллельном программировании в C#.NET (не как все, там должен знать, но основы и возможно некоторые хорошие методы), поэтому я решил повторно программировать старую мою программу, которую называют ImageSyncer. ImageSyncer является действительно простой программой, все, что он делает должен просканировать канавку папка и найти все файлы, заканчивающиеся .jpg, затем он вычисляет новое положение файлов на основе даты, они были взяты (парсинг xif-данных, или независимо от того, что это называют). После того, как местоположение генерировалось чеки программы для любых существующих файлов в том местоположении, и если Вы существуете, оно смотрит на прошлое время записи и файла для копирования, и файл "по-своему". Если это равно, файл пропускается. Если не md5 контрольная сумма обоих файлов создана и подобрана. Если там не идет ни в какое сравнение, файлу, который будет скопирован, дают новое местоположение, которое будет скопировано в (например, если он должен был быть скопирован в "C:\test.jpg", он копируется в "C:\test(1).jpg" вместо этого). Результат этой операции заполняется в очередь типа структуры, который содержит две строки, исходный файл и положение для копирования его в. Затем та очередь выполнена с помощью итераций, непока это не пусто, и файлы копируются.

Другими словами, существует 4 операции:

1. Scan directory for jpegs  
2. Parse files for xif and generate copy-location  
3. Check for file existence and if needed generate new path  
4. Copy files

И таким образом, я хочу переписать эту программу, чтобы заставить его быть параллельным и смочь выполнить несколько из операций одновременно, и я задавался вопросом, чего лучшего способа достигнуть, который будет. Я имею, придумал две различных модели, о которых я могу думать, но никакой из них не мог бы хорошо работать вообще. Первый должен параллелизировать 4 шага старой программы, так, чтобы, когда шаг нужно быть выполнен, он был сделан на нескольких потоках, и когда всем из шага 1 является законченный шаг 2, начался. Другой один (который я нахожу более интересными, потому что я понятия не имею о том, как сделать это) должен создать своего рода модель рабочего и потребителя, поэтому когда поток закончен с шагом 1, другой вступает во владение и выполняет шаг 2 в том объекте (или что-то как этот). Но, как сказано, я не знаю, является ли какой-либо из них какими-либо хорошими решениями. Кроме того, я не знаю много о параллельном программировании вообще. Я знаю, как сделать поток, и как заставить его выполнить взятие функции в объекте как его единственный параметр, и я также использовал BackgroundWorker-класс в одном случае, но я не настолько знаком ни с одним из них.

Любой вход ценился бы.

13
задан HotTester 16 May 2010 в 17:58
поделиться

3 ответа

Есть несколько вариантов:

[Но, как отметил @John Knoeller, приведенный вами пример, скорее всего, связан с последовательным вводом-выводом]

6
ответ дан 2 December 2019 в 01:31
поделиться

Это ссылка, которую я использую для потока C #: http://www.albahari.com/threading/

В виде одного PDF-файла : http://www.albahari.com/threading/threading.pdf

Для вашего второго подхода:

Я работал над некоторыми многопоточными приложениями производителя / потребителя, где каждая задача представляет собой некоторый код, который повторяется вечно. Внешний «инициализатор» запускает отдельный поток для каждой задачи и инициализирует EventWaitHandle для каждой задачи. Для каждой задачи есть глобальная очередь, которую можно использовать для производства / потребления ввода.

В вашем случае ваша внешняя программа добавит каждый каталог в очередь для Task1 и установит EventWaitHandler для Task1. Задача 1 «проснется» от своего EventWaitHandler, получит количество каталогов в своей очереди, а затем, пока счетчик больше 0, получит каталог из очереди, просканирует все файлы .jpgs и добавит каждое местоположение .jpg. во вторую очередь и установите EventWaitHandle для задачи 2. Задача 2 считывает входные данные, обрабатывает их, пересылает их в очередь для Задачи 3 ...

Может быть немного сложно заставить все блокировки работать правильно (я в основном блокирую любой доступ к очереди, даже такой простой, как получение ее счетчика). .NET 4.0 должен иметь структуры данных, которые будут автоматически поддерживать очередь производителя / потребителя без блокировок.

2
ответ дан 2 December 2019 в 01:31
поделиться

Интересная проблема. Я придумал два подхода. Первый основан на PLinq, а второй - на te Rx Framework.

Первый параллельно итерирует файлы. Второй асинхронно генерирует файлы из каталога.

Вот как это выглядит в упрощенном варианте (Первый метод требует .Net 4.0, поскольку использует PLinq)

string direcory = "Mydirectory";
    var jpegFiles = System.IO.Directory.EnumerateFiles(direcory,"*.jpg");


    // --  PLinq --------------------------------------------
    jpegFiles
    .AsParallel()
    .Select(imageFile => new {OldLocation = imageFile, NewLocation = GenerateCopyLocation(imageFile) })
    .Do(fileInfo => 
        {
            if (!File.Exists(fileInfo.NewLocation ) || 
                (File.GetCreationTime(fileInfo.NewLocation)) != (File.GetCreationTime(fileInfo.NewLocation)))
                File.Copy(fileInfo.OldLocation,fileInfo.NewLocation);
        })
    .Run();

    // -----------------------------------------------------


    //-- Rx Framework ---------------------------------------------
    var resetEvent = new AutoResetEvent(false);
    var doTheWork =
    jpegFiles.ToObservable()
    .Select(imageFile => new {OldLocation = imageFile, NewLocation = GenerateCopyLocation(imageFile) })
    .Subscribe( fileInfo => 
        {
            if (!File.Exists(fileInfo.NewLocation ) || 
                (File.GetCreationTime(fileInfo.NewLocation)) != (File.GetCreationTime(fileInfo.NewLocation)))
            File.Copy(fileInfo.OldLocation,fileInfo.NewLocation);
        },() => resetEvent.Set());

    resetEvent.WaitOne();
    doTheWork.Dispose();

    // -----------------------------------------------------
1
ответ дан 2 December 2019 в 01:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: