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