2010-08-30 65 views
1

出于好奇,是否有可能实现使用FileSystemWatcher时引发各种事件的时间间隔?是否可以在FileSystemWatcher上设置时间间隔?

谢谢!

+0

这是什么动机?有一个时间间隔就像轮询文件夹,这会破坏班级的对象。 – ChrisF 2010-08-30 18:32:06

+0

这只是好奇心,没有真正的需要。有没有办法在.net框架中进行轮询? – 2010-08-30 18:33:44

+0

@ChrisF:如果一个进程一次对文件夹进行了大量更改,那么只有在完成时才会引发该事件。 – 2010-08-30 18:36:52

回答

4

有这么采取超时FileSystemWatcher.WaitForChanged过载:

返回包含所发生的变化具体信息的结构,因为要监视更改类型和时间(A同步方法以毫秒为单位)在超时之前等待。

因此,如果您的事件没有发生在您设置过期的超时期限之前,事件不会被解雇。

我不认为有一个方法/属性设置事件之间的最短时间。

0

简答题 - 没有。该课程是基于事件的。它没有轮询功能。

0

简短的回答......也许。

这取决于如何解释这个区间。如果您希望FileSystemWatcher定期举办其中一个活动,无论实际情况是否发生变化,答案都是否定的。

但是,如果此间隔旨在控制在提升下一个事件之前必须等待的最短时间,那么确定是肯定的!诀窍是拦截事件的发生并用中间人扼杀它们。现在只有在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); } 
     } 
    } 
} 
相关问题