出于好奇,是否可以在使用FileSystemWatcher时实现引发各种事件的时间间隔?
谢谢!
答案 0 :(得分:4)
FileSystemWatcher.WaitForChanged
超载导致超时:
一种同步方法,它返回一个结构,该结构包含有关发生的更改的特定信息,给定要监视的更改类型以及超时前等待的时间(以毫秒为单位)。
因此,如果您的事件未在您设置的超时期限之前发生,则事件不会被触发。
我认为没有一个方法/属性可以设置事件之间的最短时间。
答案 1 :(得分:0)
简短回答 - 不。该课程以事件为基础。它没有轮询功能。
答案 2 :(得分:0)
简短回答......也许。
这取决于如何解释这个间隔。如果您希望FileSystemWatcher
定期提升其中一个事件,而不管某些事件是否实际发生了变化,那么答案就是否定。
但是,如果这个间隔是为了控制在提升下一个事件之前必须进行elaspe的最短时间,那么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); }
}
}
}