adicionado timeout
This commit is contained in:
parent
69139dbb17
commit
64b79bb62b
|
|
@ -20,6 +20,9 @@ namespace AgroBase.Models
|
|||
private string _id;
|
||||
public string Id { get { return _id; } }
|
||||
private Control _uiControl;
|
||||
private int _timeout = 60000;
|
||||
|
||||
private DateTime lastTick = DateTime.MinValue;
|
||||
|
||||
private bool DebugMessages = true;
|
||||
|
||||
|
|
@ -29,16 +32,18 @@ namespace AgroBase.Models
|
|||
/// <param name="taskToExecute">A tarefa assíncrona que será executada periodicamente.</param>
|
||||
/// <param name="interval">Intervalo em milissegundos entre as execuções.</param>
|
||||
/// <param name="uiControl">Controle para executar tarefas relacionadas à UI. Opcional.</param>
|
||||
public AsyncTaskTimerModel(string id, Func<Task> taskToExecute, int interval, Control uiControl = null)
|
||||
public AsyncTaskTimerModel(string id, Func<Task> taskToExecute, int interval, Control uiControl = null, int timeout = 60000)
|
||||
{
|
||||
if (string.IsNullOrEmpty(id)) throw new ArgumentNullException(nameof(id));
|
||||
if (taskToExecute == null) throw new ArgumentNullException(nameof(taskToExecute));
|
||||
if (interval <= 0) throw new ArgumentException("Interval must be greater than zero.", nameof(interval));
|
||||
if (timeout <= 0) throw new ArgumentException("Timeout must be greater than zero.", nameof(timeout));
|
||||
|
||||
_id = id;
|
||||
_stackTrace = ObterIdDoChamador();
|
||||
_taskToExecute = taskToExecute;
|
||||
_interval = interval;
|
||||
_timeout = timeout;
|
||||
_uiControl = uiControl;
|
||||
|
||||
Timers.Add(this);
|
||||
|
|
@ -110,28 +115,50 @@ namespace AgroBase.Models
|
|||
/// <summary>
|
||||
/// Verifica se o timer está em execução.
|
||||
/// </summary>
|
||||
public bool IsRunning => _cancellationTokenSource != null;
|
||||
public bool IsRunning
|
||||
{
|
||||
get
|
||||
{
|
||||
return _cancellationTokenSource != null && !_cancellationTokenSource.Token.IsCancellationRequested && lastTick.AddMilliseconds(_timeout) >= DateTime.Now;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loop interno do timer.
|
||||
/// Loop interno do timer com timeout na execução da tarefa.
|
||||
/// </summary>
|
||||
private async Task TimerLoopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
//ExibirConsole($"TICK");
|
||||
lastTick = DateTime.Now;
|
||||
|
||||
try
|
||||
{
|
||||
if (_uiControl != null)
|
||||
// Cria um token de cancelamento específico para o timeout
|
||||
var timeoutCts = new CancellationTokenSource();
|
||||
var timeoutToken = timeoutCts.Token;
|
||||
|
||||
// Define o tempo limite para a execução da tarefa
|
||||
timeoutCts.CancelAfter(_timeout);
|
||||
|
||||
var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutToken);
|
||||
|
||||
// Executa a tarefa com timeout
|
||||
var taskToRun = _uiControl != null
|
||||
? FuncoesGlobais.ExecutarMetodoComVerificacaoCrossThreadAsync(_uiControl, _taskToExecute)
|
||||
: _taskToExecute();
|
||||
|
||||
var completedTask = await Task.WhenAny(taskToRun, Task.Delay(_timeout, linkedTokenSource.Token));
|
||||
|
||||
if (completedTask == taskToRun)
|
||||
{
|
||||
// Se um controle de UI foi especificado, use-o para executar tarefas relacionadas à UI
|
||||
await FuncoesGlobais.ExecutarMetodoComVerificacaoCrossThreadAsync(_uiControl, _taskToExecute);
|
||||
// A tarefa foi concluída dentro do limite
|
||||
await taskToRun;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Caso contrário, execute a tarefa diretamente
|
||||
await _taskToExecute();
|
||||
// Timeout atingido
|
||||
ExibirConsole($"TIMEOUT - tarefa excedeu {_timeout}ms");
|
||||
}
|
||||
|
||||
// Aguarda o intervalo antes da próxima execução
|
||||
|
|
@ -154,6 +181,7 @@ namespace AgroBase.Models
|
|||
ExibirConsole($"ENCERRADO");
|
||||
}
|
||||
|
||||
|
||||
private bool _disposed = false;
|
||||
|
||||
public void Dispose()
|
||||
|
|
|
|||
Loading…
Reference in New Issue