等到使用FileSystemWatcher创建的事件复制最后一个文件

时间:2015-08-12 07:09:00

标签: c# .net filesystemwatcher

我有一些python单元测试文件。我正在将所有这些文件复制到一个文件系统观察者正在监听并触发创建事件的目录中。我希望在所有文件被复制之后运行那些的测试。正在复制的文件类似于:

unittest1.py

unittest2.py

unittestxyz.py
.
.
.

unittestRunner.py

unittestRunner.py文件导入所有其他unittest文件,并作为套件的一部分启动所有单元测试。如果我将文件复制到监视目录,Created事件将多次触发,在这种情况下会发生4次。所以,不知何故,我想“等待”,直到复制完所有文件,然后执行unittestRunner脚本。正在以编程方式复制文件,并且watcher作为Windows服务的一部分运行。

我有两个非常糟糕的解决方案,它们甚至可能不是解决方案:

一个是专门等待创建unittestRunner.py

 watcher.Created += new FileSystemEventHandler((sender, eventArgs) =>
                {
                    if (eventArgs.Name == "unittestRunner.py")
                    {
                      // Run Tests
                    }
                });

但如果在任何其他文件之前复制转轮文件,则无效。

其他方法是跟踪xml文件中某处必须复制的文件数量,并在evnet处理程序中检查当前复制文件的数量是否相同:

watcher.Created += new FileSystemEventHandler((sender, eventArgs) =>
                {
                    var totalCount = Directory.GetFiles(testFolder).Length;

                    var doc = new XmlDocument();
                    doc.Load("numberOfFilesToCopy.xml");

                    if (totalCount == doc.GetElementsByTagName("test-files")[0].ChildNodes.Count)
                    {
                        // Number is the same, all files copied, run tests
                    }
                }

在开始测试之前,是否有可能等待所有文件的所有锁定都被释放?

2 个答案:

答案 0 :(得分:2)

您可以检查每个文件以查看它们是否可访问。 从SO post开始,您可以执行以下操作:

private bool WaitForFile(FileInfo file)
{
    var attemptCount = 0;

    while(true)
    {
        try
        {
            using(file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None)) 
            { 
                return true; 
            }
        }
        catch (IOException)
        {
            //File isn't ready yet, so we need to keep on waiting until it is.
        }

        //We'll want to wait a bit between polls, if the file isn't ready.
        attemptCount++;

        if(attemptCount > 5)
        {
            break;
        }

        Thread.Sleep(1000);
    }

    return false;
}

您使用XML文件跟踪要复制的预期文件数量的想法也很好。我建议你有

var doc = new XmlDocument(); doc.Load("numberOfFilesToCopy.xml");

在方法之外,因此您不必重复加载相同的文件。

答案 1 :(得分:1)

在类似情况下,我采用这种方式:

  1. 在目标目录中创建一个“锁定”文件。只要存在此文件,一切就不会开始。
  2. 将所有需要的文件复制到目标目录。
  3. 删除“锁定”文件。

程序对“锁定”文件的“已删除”事件+一些延迟作出反应,以确保所有并发访问将被终止。

我什至后来又添加了第二个锁定文件(以另一种方式),因此在程序运行仍在进行时不会将目标目录复制到其中。