Можно ли установить интервал на FileSystemWatcher? - PullRequest
1 голос
/ 30 августа 2010

Из любопытства, возможно ли реализовать интервал, при котором различные события возникают при использовании FileSystemWatcher?

Спасибо!

Ответы [ 3 ]

4 голосов
/ 30 августа 2010

Перегрузка FileSystemWatcher.WaitForChanged, для которой требуется время ожидания:

Синхронный метод, который возвращает структуру, которая содержит конкретную информацию о произошедшем изменении, учитывая тип изменения, которое вы хотите отслеживать, и время (в миллисекундах) ожидания до истечения времени ожидания.

Так что, если ваше событие не произойдет до истечения установленного вами времени ожидания, событие не будет запущено.

Я не думаю, что есть метод / свойство, которое устанавливает минимальное время между событиями.

0 голосов
/ 30 августа 2010

Короткий ответ ... возможно.

Это зависит от того, как этот интервал будет интерпретирован. Если вы хотите, чтобы FileSystemWatcher периодически вызывал одно из его событий независимо от того, действительно ли что-то изменилось, тогда ответ будет отрицательным.

Но, если этот интервал предназначен для контроля минимального количества времени, которое должно пройти до начала следующего события, тогда asnwer, безусловно, да! Хитрость заключается в том, чтобы перехватить возникновение событий и подавить их, используя посредника. Теперь это возможно только на FileSystemWatcher (и относительно небольшом наборе других классов, основанных на событиях) из-за того, что вы можете назначить экземпляр ISynchronizeInvoke свойству SynchronizingObject. Синхронизирующий объект будет выступать в роли посредника и обеспечивать ограничение интервала.

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

public void Main()
{
  var watcher = new FileSystemWatcher();
  watcher.SynchronizingObject = new Synchronizer(TimeSpan.FromSeconds(30));
}

public class Synchronizer : ISynchronizeInvoke 
{ 
    private TimeSpan m_Interval;
    private Thread m_Thread; 
    private BlockingCollection<Message> m_Queue = new BlockingCollection<Message>(); 

    public Synchronizer(TimeSpan interval) 
    { 
        m_Interval = interval;
        m_Thread = new Thread(Run); 
        m_Thread.IsBackground = true; 
        m_Thread.Start(); 
    } 

    private void Run() 
    { 
        DateTime last = DateTime.MinValue;
        while (true) 
        { 
            Message message = m_Queue.Take();
            DateTime received = DateTime.UtcNow;
            TimeSpan span = DateTime.UtcNow - last;
            TimeSpan wait = m_Interval - span;
            if (wait > TimeSpan.Zero)
            {
              Thread.Sleep(wait);
            }
            message.Return = message.Method.DynamicInvoke(message.Args); 
            message.Finished.Set(); 
            last = received;
        } 
    } 

    public IAsyncResult BeginInvoke(Delegate method, object[] args) 
    { 
        Message message = new Message(); 
        message.Method = method; 
        message.Args = args; 
        m_Queue.Add(message); 
        return message; 
    } 

    public object EndInvoke(IAsyncResult result) 
    { 
        Message message = result as Message; 
        if (message != null) 
        { 
            message.Finished.WaitOne(); 
            return message.Return; 
        } 
        throw new ArgumentException("result"); 
    } 

    public object Invoke(Delegate method, object[] args) 
    { 
        Message message = new Message(); 
        message.Method = method; 
        message.Args = args; 
        m_Queue.Add(message); 
        message.Finished.WaitOne(); 
        return message.Return; 
    } 

    public bool InvokeRequired 
    { 
        get { return Thread.CurrentThread != m_Thread; } 
    } 

    private class Message : IAsyncResult 
    { 
        public Delegate Method = null; 
        public object[] Args = null; 
        public object Return = null; 
        public object State = null; 
        public ManualResetEvent Finished = new ManualResetEvent(false); 

        public object AsyncState 
        { 
            get { return State; } 
        } 

        public WaitHandle AsyncWaitHandle 
        { 
            get { return Finished; } 
        } 

        public bool CompletedSynchronously 
        { 
            get { return false; } 
        } 

        public bool IsCompleted 
        { 
            get { return Finished.WaitOne(0); } 
        } 
    } 
} 
0 голосов
/ 30 августа 2010

Краткий ответ - нет.Класс основан на событиях.У него нет возможности опроса.

...