Регулирование файловых операций - PullRequest
1 голос
/ 30 марта 2019

У меня есть байтовый массив, который я хочу сохранить в файле.Но я не хочу записывать в файл каждый раз, когда он обновляется, потому что он может обновляться очень часто.В настоящее время я планирую использовать подход, подобный следующему:

class ThrottleTest
{
    private byte[] _internal_data = new byte[256];

    CancellationTokenSource _cancel_saving = new CancellationTokenSource();

    public void write_to_file()
    {
        Task.Delay(1000).ContinueWith((task) =>
        {
            File.WriteAllBytes("path/to/file.data", _internal_data);
        }, _cancel_saving.Token);
    }

    public void operation_that_update_internal_data()
    {
        // cancel writing previous update
        _cancel_saving.Cancel();
        /*
         *  operate on _internal_data
         */

        write_to_file();
    }

    public void another_operation_that_update_internal_data()
    {
        // cancel writing previous update
        _cancel_saving.Cancel();
        /*
         *  operate on _internal_data
         */

        write_to_file();
    }
}

Я не думаю, что этот подход будет работать, потому что, когда я отменю токен один раз, он будет отменен навсегда, поэтому он никогда не будетнапишите в файл.

Прежде всего, мне было интересно, нахожусь ли я на правильном пути, и приведенный выше код можно заставить работать.Если нет, то какой будет лучший подход для достижения такого поведения.Кроме того, есть ли практический способ обобщить его до Dictionary<string,byte[]>, где любой byte[] может быть изменен независимо?

Ответы [ 2 ]

0 голосов
/ 31 марта 2019

Вы должны использовать Microsoft Reactive Framework (он же Rx) - NuGet System.Reactive и добавить using System.Reactive.Linq; - тогда вы можете сделать это:

public class ThrottleTest
{
    private byte[] _internal_data = new byte[256];

    private Subject<Unit> _write_to_file = new Subject<Unit>();

    public ThrottleTest()
    {
        _write_to_file
            .Throttle(TimeSpan.FromSeconds(1.0))
            .Subscribe(_ => File.WriteAllBytes("path/to/file.data", _internal_data));
    }

    public void write_to_file()
    {
        _write_to_file.OnNext(Unit.Default);
    }

    public void operation_that_update_internal_data()
    {
        /*
         *  operate on _internal_data
         */

        write_to_file();
    }

    public void another_operation_that_update_internal_data()
    {
        /*
         *  operate on _internal_data
         */

        write_to_file();
    }
}
0 голосов
/ 31 марта 2019

Я бы начал запись в файл, отменив сначала предыдущую операцию. Я бы также включил токен отмены в задачу «Задержка».

CancellationTokenSource _cancel_saving;

public void write_to_file()
{
    _cancel_saving?.Cancel();
    _cancel_saving = new CancellationTokenSource();
    Task.Delay(1000, _cancel_saving.Token).ContinueWith((task) =>
    {
        File.WriteAllBytes("path/to/file.data", _internal_data);
    }, _cancel_saving.Token);
}
...