Многопоточность с FileSystemWatching - PullRequest
0 голосов
/ 21 марта 2012

У меня есть этот код, который отлично работает для меня:

using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;

namespace Test2
{
    internal static class MyProgram
    {
        [STAThread]
        private static void Main(string[] args)
        {
            List<Plugin> plugins = new List<Plugin>
                                       {
                                           new Plugin(@"c:\temp\file1.txt"),
                                           new Plugin(@"c:\temp\file2.txt"),
                                           new Plugin(@"c:\temp\file3.txt"),
                                       };

            foreach (var plugin in plugins)
            {
                plugin.StartWatch();
                plugin.WaitHandler.WaitOne();
            }
        }
    }


    public class Plugin
    {
        private FileSystemWatcher _watcher;
        private readonly string _file;
        public AutoResetEvent WaitHandler { get; private set; }

        public Plugin(string file)
        {
            _file = file;
            Console.WriteLine("Creating plugin for file {0}", _file);
            WaitHandler = new AutoResetEvent(false);
        }

        public void StartWatch()
        {
            Console.WriteLine("Starting watching {0}", _file);
            WaitHandler.Reset();
            FileInfo fileInfo = new FileInfo(_file);
            if (fileInfo.Directory != null)
            {
                _watcher = new FileSystemWatcher(fileInfo.Directory.FullName, fileInfo.Name);
                _watcher.NotifyFilter = NotifyFilters.LastWrite;
                _watcher.Changed += OnChanged;
                _watcher.EnableRaisingEvents = true;
            }
        }

        private void OnChanged(object source, FileSystemEventArgs e)
        {
            Console.WriteLine("Finished watching file {0}", _file);
            _watcher.Dispose();
            WaitHandler.Set();
        }
    }
}

Результат, напечатанный из кода, следующий (что работает нормально и важно):

Creating plugin for file c:\temp\file1.txt
Creating plugin for file c:\temp\file2.txt
Creating plugin for file c:\temp\file3.txt
Starting watching c:\temp\file1.txt
Finished watching file c:\temp\file1.txt
Starting watching c:\temp\file2.txt
Finished watching file c:\temp\file2.txt
Starting watching c:\temp\file3.txt
Finished watching file c:\temp\file3.txt

Проблема, с которой я столкнулся, заключается в том, что я хочу сделать свою программу многопоточной, а в фоновом режиме - запустить другой поток.я не могу сделать это с этим дизайном, потому что основной поток заблокирован AutoResetEvent.Другой поток, который я хочу добавить, - это поток, который будет прослушивать файл с именем «AbortFlagFile.txt».как только "AbortFlagFile.txt" будет изменен, чем я хочу, чтобы моя программа была прервана.Я думал, может быть, создать PluginEndEvent, который будет запущен после завершения OnChange ().

Для меня очень важно, чтобы программа создавала журналы в том же порядке, в котором я писал выше. Спасибо!

1 Ответ

0 голосов
/ 21 марта 2012

Объявление массива ручек ожидания и счетчика

private static WaitHandle[] waithandles;
private static int waitcount;

В конструкторе инициализируйте его

waithandles = new WaitHandle[3] { new AutoResetEvent(false), new AutoResetEvent(false) };

, вам также понадобится функция для увеличения счетчика потоков

private static void incThreadCounter()
{
        lock (sobj)
    {
    waitcount++;
    }
}

в коде, где вы инициализируете свой поток, вызовите incThreadCounter ()

Я на самом деле выполняю функцию обратного вызова после того, как поток будет помещен в буфер.Предотвращает ложные подсчеты

в области, в которой ваш автосброс устанавливает цикл while, и уменьшает счетчик нитей, когда они сигнализируют

while (waitcount > 0)
{
    WaitHandle.WaitAny(waithandles, 5000);
    waitcount--;
}

Когда счетчик равен 0, вы переходите к следующемучасть, которая может наматывать дополнительные потоки

Если вы хотите убедиться, что поток 2 работает после потока 1, вы захотите использовать вариант логики выше.Фактически, если поток 2 всегда должен запускаться после потока 1, а поток 3 всегда должен запускаться после потока 2, тогда вам действительно не нужна многопоточность.Потоки полезны, только если есть процессы, которые могут работать одновременно.

Надеюсь, это поможет

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