C#:实时将高速数据(50M / s)写入本地磁盘

时间:2013-06-18 03:08:15

标签: c# performance file real-time

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

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

添加更多信息: hareware可以支持我的应用程序写入,我多次运行应用程序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;
    }
}

0 个答案:

没有答案