В моем приложении у меня есть класс, отвечающий за сохранение в файле текущего статуса приложения (модели) при его изменении:
public class BackupAgent
{
private readonly Model _model;
public BackupAgent(Model model)
{
_model = model;
_model.Changed += Save;
}
private void Save()
{
// serialize model and save it to a file
...
}
}
Он работает нормально, но при большом количестве модификаций файл записывается снова и снова.
Я вышел с RecurringActionHandler которые гарантируют, что
- в
Saveметод не вызывается дважды за минимальное время. - в
Saveметод всегда вызывается (рано или поздно) после модификации.
Он используется так:
public class BackupAgent
{
private readonly Model _model;
private readonly RecurringActionHandler _saveHandler;
public BackupAgent(Model model)
{
_model = model;
_saveHandler = new RecurringActionHandler(Save, TimeSpan.FromMilliseconds(100));
_model.Changed += RequestSave;
}
private void RequestSave() => _saveHandler.RequestCall();
private void Save()
{
// serialize model and save it to a file
...
}
}
Вот моя текущая реализация:
public class RecurringActionHandler
{
// Action to call recurrently
private readonly Action _action;
// a lock to protect _hasTask and _isCallRequested
private readonly object _lock = new();
// minimum time span between two calls to _action
private readonly TimeSpan _minimumRestTime;
// a boolean indicating whether a task is already running or not
private bool _hasTask;
// a boolean indicating whether a call to _action is request or not
private bool _isCallRequested;
public RecurringActionHandler(Action action, TimeSpan minimumRestTime)
{
_action = action;
_minimumRestTime = minimumRestTime;
}
public void RequestCall()
{
lock (_lock)
{
_isCallRequested = true;
if (_hasTask)
return;
_hasTask = true;
Task.Run(Work);
}
}
private async Task Work()
{
for (;;)
{
lock (_lock)
{
if (!_isCallRequested)
{
_hasTask = false;
break;
}
_isCallRequested = false;
}
_action();
await Task.Delay(_minimumRestTime).ConfigureAwait(false);
}
}
}
Я ищу совета по коду и именам методов / классов. Является Throttling подходящее имя здесь?
