C# 有人知道如何运行这个扩展版本的FileSystemWatcher吗?

C# 有人知道如何运行这个扩展版本的FileSystemWatcher吗?,c#,filesystemwatcher,C#,Filesystemwatcher,我发现了这段代码,它看起来像是微软的FileSystemWatcher的C版本的固定版本。但问题是我不知道如何使用或运行它。请有专业知识的人帮我解释一下好吗?如何使用此代码 我相信原始的来源和解释就在这里。我试图联系发起者,但无法得到回复 使用系统; 使用系统集合; 使用System.Collections.Concurrent; 使用System.Collections.Generic; 使用System.Diagnostics.Contracts; 使用System.IO; 使用系统线程;

我发现了这段代码,它看起来像是微软的FileSystemWatcher的C版本的固定版本。但问题是我不知道如何使用或运行它。请有专业知识的人帮我解释一下好吗?如何使用此代码

我相信原始的来源和解释就在这里。我试图联系发起者,但无法得到回复

使用系统;
使用系统集合;
使用System.Collections.Concurrent;
使用System.Collections.Generic;
使用System.Diagnostics.Contracts;
使用System.IO;
使用系统线程;
命名空间Fws.Collections
{
/// 
///检测目录中文件的到达,并使它们可供客户端类使用
///作为完全路径文件名的IEnumerable
///类生成在构造对象时存在的文件。此外,它不是IDisposable。
/// 
/// 
/// 
///如果一个文件在这个类的构造函数执行期间到达,它可能会被报告超过
///此外,一些程序编写文件的方式使底层的FileSystemWatcher
///将多次触发Create事件。在这些情况下,此类将生成
///多次存档。
/// 
///客户端代码必须考虑到这些可能性
///通过等待生成的文件停止、过滤掉重复的文件等来优化这些文件。
/// 
/// 
///此类是线程安全的:多个线程可以枚举
///该类的单个实例,每个线程将获得所有文件。
/// 
/// 
公共密封类CreatedFileCollection:IEnumerable
{
#区域字段
只读字符串_目录;
只读字符串_filePattern;
只读取消令牌\u取消令牌;
#端区
#用于收集结果的区域嵌套类
/// 
///在一个GetEnumerator调用中找到的文件队列。
/// 
私有密封类CreatedFileQueue:IDisposable
{
只读ConcurrentQueue _queue=新ConcurrentQueue();
只读信号量lim_fileEnqueued=新信号量lim(0);
/// 
///尝试从队列中获取文件。
/// 
///文件名(如果立即可用)。
///如果获得文件,则为True;如果没有,则为false。
public bool TryDequeue(输出字符串文件名,CancellationToken CancellationToken)
{
fileName=null;
//尽可能避免操作取消异常。
if(cancellationToken.IsCancellationRequested)
返回false;
尝试
{
_fileEnqueued.Wait(cancellationToken);
返回_queue.TryDequeue(out文件名);
}
捕获(操作取消异常)
{
返回false;
}
}
/// 
///处理封闭类的FileSystemWatcher的创建事件。
/// 
///这个物体。
///新文件的参数。
已创建公共无效文件(对象发送方、文件系统目标)
{
_排队。排队(如全路径);
_fileEnqueued.Release();
}
公共空间处置()
{
_fileEnqueued.Dispose();
}
}
#端区
#区域构造函数
/// 
///构造器。
/// 
///此类将终止的枚举
///仅当令牌进入“已取消”状态时才提交文件。
///要监视的目录。
///要在文件名中匹配的模式。例如:“*.txt”。
///Null表示所有文件。
///队列中可能会返回重复项。请参阅类的备注。
public CreatedFileCollection(CancellationToken CancellationToken,字符串目录,字符串文件模式=null)
{
Contract.Requires(目录!=null);
Contract.Requires(cancellationToken!=null);
如果(!Directory.Exists(Directory))
抛出新的ArgumentException(String.Format(“目录{0}”不存在。”,目录));
_目录=目录;
_filePattern=filePattern??“*”;
_cancellationToken=cancellationToken;
}
#端区
#区域方法
/// 
///获取一个枚举数,该枚举数将生成文件,直到取消CanellationToken。
/// 
///完全路径文件名。
/// 
///可以多次返回文件名。
/// 
公共IEnumerator GetEnumerator()
{
如果(!\u cancellationToken.IsCancellationRequested)
{
使用(var-watcher=newfilesystemwatcher(_目录,_文件模式))
{
使用(var queue=new CreatedFileQueue())
{
//将NotifyFilter限制为创建事件所需的所有内容。
//这将使FileSystemWatcher的缓冲区被淹没的可能性降至最低。
watcher.NotifyFilter=NotifyFilters.FileName;
watcher.Created+=queue.FileCreated;
watcher.EnableRaisingEvents=true;
//请注意,如果文件在以下循环中到达,它将被放置在队列中
//两次:一次是在引发Create事件时,一次是由循环本身引发。
foreach(目录.GetFiles(_目录,_文件模式,SearchOption.TopDirect)中的var文件
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.IO;
using System.Threading;

namespace Fws.Collections
{
    /// <summary>
    /// Detects the arrival of files in a directory and makes them available to a client class
    /// as an IEnumerable of fully pathed file names. Unlike the .NET FileSystemWatcher, this 
    /// class yields files that exist when the object is constructed. Also, it is not an IDisposable.
    /// </summary>
    /// <remarks>
    /// <para>
    /// If a file arrives during the execution of this class's constructor, it may be reported more than
    /// once. Also, some programs write their files in such a way that the underlying FileSystemWatcher
    /// will fire a Create event more than once. In those cases, this class will yield the
    /// file multiple times.
    /// </para><para>
    /// Client code must account for these possibilities. It is envisioned that wrapping classes may
    /// refine the yielded files by waiting for them to quiesce, filtering out duplicates, etc.
    /// </para>
    /// <para>
    /// This class is thread-safe: more than one thread may enumerate the files presented by a 
    /// single instance of this class, and each thread will get all the files.
    /// </para>
    /// </remarks>
    public sealed class CreatedFileCollection : IEnumerable<string>
    {
        #region Fields
        readonly string _directory;
        readonly string _filePattern;
        readonly CancellationToken _cancellationToken;
        #endregion

        #region Nested Class to Collect Results
        /// <summary>
        /// A queue of files found within one GetEnumerator call.
        /// </summary>
        private sealed class CreatedFileQueue : IDisposable
        {
            readonly ConcurrentQueue<string> _queue = new ConcurrentQueue<string>();
            readonly SemaphoreSlim _fileEnqueued = new SemaphoreSlim(0);

            /// <summary>
            /// Attempt to get a file from the queue.
            /// </summary>
            /// <param name="fileName">The name of the file, if one is immediately available.</param>
            /// <returns>True if got a file; false if not.</returns>
            public bool TryDequeue(out string fileName, CancellationToken cancellationToken)
            {
                fileName = null;
                // Avoid the OperationCanceledException if we can.
                if (cancellationToken.IsCancellationRequested)
                    return false;
                try
                {
                    _fileEnqueued.Wait(cancellationToken);
                    return _queue.TryDequeue(out fileName);
                }
                catch (OperationCanceledException)
                {
                    return false;
                }
            }

            /// <summary>
            /// Handles the Created event of the enclosing class's FileSystemWatcher.
            /// </summary>
            /// <param name="sender">This object.</param>
            /// <param name="e">Args for the new file.</param>
            public void FileCreated(object sender, FileSystemEventArgs e)
            {
                _queue.Enqueue(e.FullPath);
                _fileEnqueued.Release();
            }

            public void Dispose()
            {
                _fileEnqueued.Dispose();
            }
        }
        #endregion

        #region Constructor
        /// <summary>
        /// Constructor. 
        /// </summary>
        /// <param name="cancellationToken">This class will terminate the enumeration of
        /// files when and only when the token enters the canceled state.</param>
        /// <param name="directory">The directory to watch.</param>
        /// <param name="filePattern">A pattern to match in the file name. Example: "*.txt".
        /// Null means all files.</param>
        /// <remarks>Duplicates may be returned on the queue. See remarks for the class.</remarks>
        public CreatedFileCollection(CancellationToken cancellationToken, string directory, string filePattern=null)
        {
            Contract.Requires(directory != null);
            Contract.Requires(cancellationToken != null);

            if (!Directory.Exists(directory))
                throw new ArgumentException(String.Format("Directory '{0}' does not exist.", directory));

            _directory = directory;
            _filePattern = filePattern ?? "*";
            _cancellationToken = cancellationToken;
        }
        #endregion

        #region Methods
        /// <summary>
        /// Get an enumerator that will yield files until the CanellationToken is canceled.
        /// </summary>
        /// <returns>Fully pathed file names.</returns>
        /// <remarks>
        /// It is possible for a file name to be returned from more than once.
        /// </remarks>
        public IEnumerator<string> GetEnumerator()
        {
            if (!_cancellationToken.IsCancellationRequested)
            {
                using (var watcher = new FileSystemWatcher(_directory, _filePattern))
                {
                    using (var queue = new CreatedFileQueue())
                    {
                        // Restrict the NotifyFilter to all that's necessary for Create events.
                        // This minimizes the likelihood that FileSystemWatcher's buffer will be overwhelmed.
                        watcher.NotifyFilter = NotifyFilters.FileName;

                        watcher.Created += queue.FileCreated;

                        watcher.EnableRaisingEvents = true;
                        // Note that if a file arrives during the following loop, it will be placed on the queue
                        // twice: once when the Create event is raised, and once by the loop itself.
                        foreach (var file in Directory.GetFiles(_directory, _filePattern, SearchOption.TopDirectoryOnly))
                        {
                            queue.FileCreated(this, new FileSystemEventArgs(WatcherChangeTypes.Created, _directory, Path.GetFileName(file)));
                        }

                        if (!_cancellationToken.IsCancellationRequested)
                        {
                            string fileName;
                            while (queue.TryDequeue(out fileName, _cancellationToken))
                                yield return fileName;
                        }
                    }
                }
            }
        }

        /// <summary>
        /// Required method for IEnumerable.
        /// </summary>
        /// <returns>The generic enumerator, but as a non-generic version.</returns>
        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
        #endregion
    }
}
public static void Main()
{
    var watcher = new CreatedFileCollection(CancellationToken.None, "c:\\test");

    var enumerator = watcher.GetEnumerator();

    Task.Run(() =>
    {
        //This will block until either a new file is created or the 
        //passed CancellationToken is cancelled.
        while (enumerator.MoveNext()) 
        {
            Console.WriteLine("New File - " + enumerator.Current);
        }
    });

    Console.ReadLine();
}