Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/325.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#_Io - Fatal编程技术网

C# “阅读大量文件”;同时";

C# “阅读大量文件”;同时";,c#,io,C#,Io,我正在使用FileSystemWatcher来捕获文件夹中任何文件中创建的、更改的、删除的和重命名的更改 在这些更改中,我需要对这些文件的内容执行简单的校验和。简单地说,我正在打开一个文件流并将其传递给MD5类: private byte[] calculateChecksum(string frl) { using (FileStream stream = File.Open(frl, FileMode.Open, FileAccess.Read, FileShare.ReadWrit

我正在使用
FileSystemWatcher
来捕获文件夹中任何文件中创建的
更改的
删除的
重命名的
更改

在这些更改中,我需要对这些文件的内容执行简单的校验和。简单地说,我正在打开一个文件流并将其传递给MD5类:

private byte[] calculateChecksum(string frl)
{
    using (FileStream stream = File.Open(frl, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
    {
        return this.md5.ComputeHash(stream);
    }
}
问题在于我需要处理的文件数量。例如,假设我在一个文件夹中创建了200个文件,然后复制所有文件并粘贴到同一文件夹中。此操作将导致200个事件和200个执行


如何解决此类问题?

FileSystemWatcher
handler中,处理程序将任务放入将由某个工作者处理的队列。工作人员可以以目标速度或/和频率处理校验和计算任务。可能一个工人会更好,因为许多读卡器可以通过许多读搜索减慢硬盘速度

尝试阅读有关BlockingCollection的内容:

生产者和消费者数据流模式

此外,您还可以创建多个消费者,只需同时调用Take或TryTake即可-每个商品将仅由一个消费者消费。但考虑到在这种情况下,一个文件可以由许多工作人员处理,而多个hdd读卡器可能会降低hdd的速度

UPD如果有多个worker,最好创建多个BlockingCollection,并使用索引将文件推送到队列中:

我已经设置了一个cosumer-producer模式来解决这个问题,我尝试使用线程池来平滑大量工作,共享一个
BlockingCollection

阻止收集和线程池

private BlockingCollection<Index.ResourceIndexDocument> documents;
this.pool = new SmartThreadPool(SmartThreadPool.DefaultIdleTimeout, 4);
this.documents = new BlockingCollection<string>();
public void warn(string channel, string frl)
{
    this.pool.QueueWorkItem<string, string>(
        (file) => this.files.Add(file),
        channel,
        frl
    );
}
Task.Factory.StartNew(() =>
{
    Index.ResourceIndexDocument document = null;
    while (this.documents.TryTake(out document, TimeSpan.FromSeconds(1)))
    {
        IEnumerable<Index.ResourceIndexDocument> documents = this.documents.Take(this.documents.Count);
        Index.IndexEngine.Instance.index(documents);
    }
},
TaskCreationOptions.LongRunning
);
消费者

private BlockingCollection<Index.ResourceIndexDocument> documents;
this.pool = new SmartThreadPool(SmartThreadPool.DefaultIdleTimeout, 4);
this.documents = new BlockingCollection<string>();
public void warn(string channel, string frl)
{
    this.pool.QueueWorkItem<string, string>(
        (file) => this.files.Add(file),
        channel,
        frl
    );
}
Task.Factory.StartNew(() =>
{
    Index.ResourceIndexDocument document = null;
    while (this.documents.TryTake(out document, TimeSpan.FromSeconds(1)))
    {
        IEnumerable<Index.ResourceIndexDocument> documents = this.documents.Take(this.documents.Count);
        Index.IndexEngine.Instance.index(documents);
    }
},
TaskCreationOptions.LongRunning
);
Task.Factory.StartNew(()=>
{
Index.ResourceIndexDocument文档=null;
while(this.documents.TryTake(out document,TimeSpan.FromSeconds(1)))
{
IEnumerable documents=this.documents.Take(this.documents.Count);
Index.IndexEngine.Instance.Index(文档);
}
},
TaskCreationOptions.LongRunning
);

您考虑过工作池吗?如中所示:将作业添加到某个执行引擎中,并在作业进入时(根据可用线程的数量)对其进行处理。我认为某种c#async wait magic能够以非常简单的方式实现这一点。如果打开这么多文件会导致性能问题,您可以实现队列并限制工作线程的数量。您已经有了一个工作池。检查,是的。它需要一个混合:生产者-消费者线程模式和
消费者池。有
生产者
(FileSystemWatcher的事件)产生要处理的项,有几个
消费者
处理它们。下一步是,如何合并或联接操作。因此,我需要一个
consumer
同时处理
x
项。@Jordi,您可以创建多个consumer,但要小心,它可能会使硬盘性能下降,因为我不了解上一个UPD。“使用索引“?@Jordi在QUU中推送文件”为防止多个工作人员同时处理一个文件时出现这种情况,必须始终使用同一个工作人员处理一个文件,如果您为每个使用者进行BlockingCollection并使用某些规则为每个文件选择队列,则可以确定。现在,我明白了,我需要为我的
BlockingCollection
提供信息。现在的问题是,我不太明白如何开发一个
消费者
,它在这个集合中永久地出现,并根据实际元素从
BlocingCollection
中提取
x
并处理它们……我现在面临的问题是我需要使用一组文件
GetConsumingEnumerable()
枚举
BlockingCollection
上的每个
string
,但是我需要同时处理所有元素。属性“Count”和方法TryTake几乎没有超时()尝试使用属性“Count”获取集合中的所有元素并将其放入数组或smth。此外,BlockingCollection包含方法TryTake,若您在循环中使用该方法时几乎并没有超时,那个么您可以读取所有已存在的方法。在你得到超时时间后,请接受usal。我已经改变了我的消费者。我不知道这是否如你所评论的那样。现在的问题是,采用
方法。它不会从反收集中删除元素!