i具有以下事件委托,基本上将包含一系列字节,并将其附加到文件流上。一旦写了1000次,它由局部变量counter
跟踪,我想关闭当前的文件流并打开新的文件。
我阅读了FileStream的文档,并建议使用FileStream.WriteAsync()
进行更好的性能。
public void WriteData(byte[] data)
{
counter++;
if (counter == 1000)
{
counter = 0;
// Close the current filestream and open a new one.
filestream.Dispose();
filestream = new FileStream(this.outputPath, FileMode.Create,
FileAccess.Write, FileShare.None, 4096, true);
}
filestream.WriteAsync(data, 0, data.Length);
}
但是,在上面的功能中,我的假设是,在我调用filestream.Dispose()
之前,所有WriteAsync()
调用尚未完成。有没有办法确保我所有WriteAsync()
呼叫完成后仅Dispose()
?请注意,此事件代表被称为每秒1,000-2,000次,Writeasync将每次呼叫240 KB复制到SSD。
我能想到的一种解决方案是,而不是立即立即处理每个Filestream
,我可以将其存储在Filestream
的数组中,然后一旦完成整个数据编写过程,就会处理它们,并且没有更多的事件正在启动。那会起作用吗?即使那样,我如何有效地"等待"直到所有WriteAsync()
呼叫完成?
虽然不是确切问题的答案,但根据评论的后续行动,我建议您执行以下操作:
- 在发射事件的任何内容中创建
ConcurrentQueue
- 在每个事件中,添加到该队列
- 创建一个单独的线程,该线程为队列提供服务,脱水事件并将其写入磁盘。然后,您可以准确控制要打开,写入,重命名等的频率,并且在文件活动上没有线程并发问题。
- 根据您的要求,在作者线程中,您可以每秒钟左右轮询队列,或者您可以使用
WaitHandle
S更复杂它中有n个项目等。当您如此频繁地积累数据时,也许投票很好,因为您几乎总是会找到要编写的数据。 - 您显然需要干净地关闭应用程序 - 例如停止从事件写作,单身到写作线程以停止,将其冲洗到磁盘上,等待停止。
这是更多的工作,但是您得到了:
- 保证订单
- 几乎没有时间在活动处理程序上
- 没有并发问题(除了管理设置和拆除外)
- 书面延误 - 例如由于操作系统,磁盘,网络 - 请勿阻止主应用
- 如果您损失了电源或中止应用程序,则失去事件数据的风险(您将拥有任何解决方案,任何解决方案都不会等待每个事件后都没有编写数据)
可能有开箱即用的解决方案为此(想到使用缓冲的Log4net Appender);这是如果您想滚动。
您可以使用"标准"线程(即Thread
)执行此操作,也可以将写作线程创建为Task
。