C#:实时将高速数据(50米/秒)写入本地磁盘
我的应用程序需要将接收到的UDP数据连续写入磁盘,速度大约为40M/s-50M/s。我目前的逻辑是,所有数据都缓存在队列中,并创建一个BinaryWriter将队列数据写入本地磁盘。它在大多数情况下运行良好,但有时写入速度会非常慢,导致缓存数据过大,然后我的应用程序崩溃 有没有办法提高写入文件的速度并保持稳定的写入速度?或者我必须调整我的硬件 添加更多信息: 该硬件可以支持我的应用程序编写,我多次运行应用程序1小时,应用程序只是偶尔崩溃 这是我要写的类文件:C#:实时将高速数据(50米/秒)写入本地磁盘,c#,performance,file,real-time,C#,Performance,File,Real Time,我的应用程序需要将接收到的UDP数据连续写入磁盘,速度大约为40M/s-50M/s。我目前的逻辑是,所有数据都缓存在队列中,并创建一个BinaryWriter将队列数据写入本地磁盘。它在大多数情况下运行良好,但有时写入速度会非常慢,导致缓存数据过大,然后我的应用程序崩溃 有没有办法提高写入文件的速度并保持稳定的写入速度?或者我必须调整我的硬件 添加更多信息: 该硬件可以支持我的应用程序编写,我多次运行应用程序1小时,应用程序只是偶尔崩溃 这是我要写的类文件: class BufferedFile
class BufferedFileStorageManager : IFileStorageManager
{
private BinaryWriter writer;
private ConcurrentQueue<byte[]> buffer;
private bool isWriting;
private bool isClosed;
public void Open(string filePath)
{
buffer = new ConcurrentQueue<byte[]>();
writer = new BinaryWriter(new FileStream(filePath, FileMode.Create));
isWriting = false;
isClosed = false;
}
/// <summary>
/// Writes the specified data syncronizly. Method will return after writing finished.
/// </summary>
/// <param name="data">The data.</param>
public void Write(byte[] data)
{
writer.Write(data);
}
/// <summary>
/// Write the data asyncronizly.
/// </summary>
/// <param name="data">The data.</param>
/// <returns></returns>
public async Task WriteAsync(byte[] data)
{
if (isClosed)
{
var closedTask = Task.Factory.StartNew(() => LogManager.Warn("File is closed, skip writing data."));
await closedTask;
}
else
{
buffer.Enqueue(data);
var writeTask = Task.Factory.StartNew(WriteInQueue);
await writeTask;
}
}
private void WriteInQueue()
{
if (isWriting)
return;
isWriting = true;
byte[] data;
while (buffer.TryDequeue(out data))
{
writer.Write(data);
}
isWriting = false;
}
/// <summary>
/// Close file. Method will return until all pending data is written to file
/// </summary>
public void Close()
{
WriteInQueue();
while (isWriting)
{
Thread.Sleep(1);
}
writer.Close();
}
public async Task CloseAsync()
{
isClosed = true;
var closeTask = new Task(Close);
closeTask.Start();
await closeTask;
writer.Dispose();
writer = null;
}
}
class BufferedFileStorageManager:IFileStorageManager
{
私人二进制编写器;
私有并发队列缓冲区;
私人写作;
私人住宅被关闭;
公共无效打开(字符串文件路径)
{
缓冲区=新的ConcurrentQueue();
writer=newbinarywriter(newfilestream(filePath,FileMode.Create));
isWriting=false;
isClosed=false;
}
///
///同步写入指定的数据。方法将在写入完成后返回。
///
///数据。
公共无效写入(字节[]数据)
{
writer.Write(数据);
}
///
///异步写入数据。
///
///数据。
///
公共异步任务WriteAsync(字节[]数据)
{
如果(已关闭)
{
var closedTask=Task.Factory.StartNew(()=>LogManager.Warn(“文件已关闭,跳过写入数据”);
等待关闭任务;
}
其他的
{
排队(数据);
var writeTask=Task.Factory.StartNew(WriteInQueue);
等待书面质询;
}
}
私有无效写入查询()
{
如果(正在写入)
返回;
isWriting=true;
字节[]数据;
while(buffer.TryDequeue(out数据))
{
writer.Write(数据);
}
isWriting=false;
}
///
///方法将返回,直到所有挂起的数据都写入文件
///
公众假期结束()
{
WriteInQueue();
(写作时)
{
睡眠(1);
}
writer.Close();
}
公共异步任务CloseAsync()
{
isClosed=true;
var closeTask=新任务(关闭);
closeTask.Start();
等待完成任务;
writer.Dispose();
writer=null;
}
}
第一个问题:即使在理想的负载测试下,硬件也能维持这种写入水平吗?(使用存储基准测试工具)下一个问题:是什么使写入速度变得“非常慢”?其他磁盘活动(防病毒和备份工具确实会降低磁盘访问速度)?C#应用程序(与系统IO无关)出现了一些无法解释的速度减慢?(使用perfmon绘制基本资源使用情况图。)在不确切了解您是如何读写的情况下,我的第一个建议是确保您正在缓冲写操作,一次较大的写操作通常比许多较小的写操作更快(开销更小)。您是否检查了打开的线程数。可能是线程不足。这似乎不太可能,但值得一查。另外,Re@Matthew评论。虽然德克。。。{writer.Write(数据);}。可以缓冲到本地字节字符串,然后写入一个块。@user2246674:是的,硬件支持写入级别,应用程序运行在一台非常干净的机器上,而不运行其他应用程序。我的应用程序只是偶尔会崩溃。有时应用程序IO会慢一段时间,内存会大量增加,然后崩溃。我不知道如何检查它,以确定是代码问题还是硬件IO问题?@Matthew:谢谢Matthew。我添加了我的书写代码。