0

我的应用程序必须将接收到的 UDP 数据连续写入磁盘,速度约为 40M/s - 50M/s。我目前的逻辑是所有数据都缓存在一个队列中,并创建一个 BinaryWriter 将队列数据写入本地磁盘。它大部分时间都运行良好,但有时写入速度会很慢,导致缓存数据太大,然后我的应用程序崩溃。

有什么方法可以提高写入文件速度,保持稳定的写入速度?或者我必须调整我的硬件?

添加更多信息:该软件可以维持我的应用程序编写,我多次运行应用程序 1 小时,应用程序只是偶尔崩溃。

这是我写文件的类:

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;
    }
}
4

0 回答 0