Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 静候活动_C#_Multithreading_Timer - Fatal编程技术网

C# 静候活动

C# 静候活动,c#,multithreading,timer,C#,Multithreading,Timer,我需要创建一个方法来监听事件并在调用另一个函数之前等待一定量的静默 具体地说,我正在收听一个目录以获取文件更新。当文件发生更改时,将调用我的“directoryUpdate”函数。从那里,我将文件添加到一个列表中,并创建一个名为“timerThread”的线程,该线程将休眠2秒。当该线程完成睡眠时,它调用一个“gatherFinished”函数 但由于如果10个文件发生更改,directoryUpdate会同时被调用10次,因此它会启动10个线程,这似乎是一种糟糕的方式 最后,我想要一个在两秒钟

我需要创建一个方法来监听事件并在调用另一个函数之前等待一定量的静默

具体地说,我正在收听一个目录以获取文件更新。当文件发生更改时,将调用我的“directoryUpdate”函数。从那里,我将文件添加到一个列表中,并创建一个名为“timerThread”的线程,该线程将休眠2秒。当该线程完成睡眠时,它调用一个“gatherFinished”函数

但由于如果10个文件发生更改,directoryUpdate会同时被调用10次,因此它会启动10个线程,这似乎是一种糟糕的方式

最后,我想要一个在两秒钟内发生的文件更改列表。我想如果有一种方法可以在每次发生变化时将睡眠时间重置为2秒,然后等待2秒结束,那么我就可以得到我所需要的。但据我所知,没有办法重置计时器

这样做的最佳方式是什么

更新
谢谢你的回答。我很抱歉把重点放在获取文件列表上。事件(文件更改)应该无关紧要。我想集中精力确保在正确的时间调用“gatherFinished”一次,即在所有相关事件停止触发后2秒。我的问题是等待的性质,而不是文件或集合的性质。

一种方法是将每个更新的文件添加到一个列表中,并附上它们添加的时间戳。然后,当您的2秒计时器启动时,您可以检查列表中时间戳早于上次启动时间的任何项目。

您可以使用AutoResetEvent并等待2秒。如果事件被触发,则循环并再等待2秒钟

        AutoResetEvent resetTimer = new AutoResetEvent(false);

        ...

        private void TimerJob()
        {
            ...

            // The thread will sleep and loop until 
            // 2 seconds elapse without directory changes 
            while (resetTimer.WaitOne(2000)) {}

            ...
        }

        private void ResetTimer()
        {
            resetTimer.Set();
        }
注意:我没有输入任何代码来指定如何同步将接收目录更改的线程和计时器线程。你必须自己做。

嘿,乔诺, 这实际上是一个非常有趣的问题

如果我理解正确,您正在使用FileSystemWatcher或其他类似对象监视文件夹

每次添加或更改文件时,您都会收到一个事件

现在的问题是,这个事件可能会在相对随机的时间引发,如果您试图记录彼此在2秒内修改过的所有文件,您将拥有许多对象集合

我要做的是创建一个
列表
,其中
MyFileChangeClass
是您用来跟踪已更改信息的任何结构

处理文件修改事件时,使用必要的详细信息创建新的
MyFileChangeClass
,并迭代外部列表。对于每个列表,检查第一个
MyFileChangeClass
在当前文件修改之前的时间戳是否小于2秒,如果是,请将文件修改添加到内部列表中

遍历完整个列表后,向外部列表添加一个新的
列表
,该列表仅填充当前的
MyFileChangeClass
。这将确保将来的修改可以与最新的修改相关联,并且您拥有在两秒内发生的所有修改分组

在整个过程中,我会使用
TryEnterWriteLock()
包含一个锁,可能是一个
ReaderWriterLockSlim

我希望这有帮助-如果你需要更多的细节,请让我知道,但显然你知道一点你在做什么,可能只是需要一些逻辑帮助,因为这是一个奇怪的问题

祝你好运
Adam

我假设您正在使用
FileSystemWatcher
类来监视文件系统的更改。您的问题非常适合生产者-消费者模式。在您的情况下,生产者是
FileSystemWatcher
,它将更改的文件添加到队列中。一旦文件名出现,使用者将从队列中退出队列。这种模式的优点是只涉及一个工作线程,所有文件更改都将按接收顺序处理

这里有一些代码让你开始

public class Example
{
  private BlockingCollection<string> m_Queue = new BlockingCollection<string>();

  public Example()
  {
    var thread = new Thread(Consumer);
    thread.IsBackground = true;
    thread.Start();
  }

  public void QueueChangedFile(string filePath)
  {
    m_Queue.Add(filePath);
  }

  private void Consumer()
  {
    while (true)
    {
      // The Take method blocks until an item appears in the queue.
      string filePath = m_Queue.Take();
      // Do whatever you need to do with the file here.
    }
  }
}
公共类示例
{
private BlockingCollection m_Queue=新建BlockingCollection();
公共示例()
{
var线程=新线程(使用者);
thread.IsBackground=true;
thread.Start();
}
public void QueueChangedFile(字符串文件路径)
{
m_Queue.Add(文件路径);
}
私人用户()
{
while(true)
{
//Take方法会一直阻塞,直到队列中出现一个项。
string filePath=m_Queue.Take();
//对这里的文件做任何你需要做的事情。
}
}
}
FileSystemWatcher
事件处理程序中,您可以调用
QueueChangedFile
。在调用
Take
之后,在
Consume
方法中添加您认为处理文件更改所必需的任何代码。您可以根据需要使逻辑复杂化。如果您需要跟踪更改发生的时间(以便以后可以确定哪些文件在彼此相隔2秒的时间内更改),那么您可以创建一个简单的类来存储文件路径和更改时间,并让队列存储该包装类,而不是让队列保存
字符串