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