Implementada lógica de actualización segura en PLCViewModel para evitar actualizaciones concurrentes y mejorar la gestión de tiempos de espera.
This commit is contained in:
parent
4a05bad08a
commit
4aa1e8ec27
136
PLCViewModel.cs
136
PLCViewModel.cs
|
@ -57,6 +57,13 @@ namespace LibS7Adv
|
||||||
private DateTime _lastUpdateStartTime = DateTime.MinValue;
|
private DateTime _lastUpdateStartTime = DateTime.MinValue;
|
||||||
private TimeSpan _updateTimeout = TimeSpan.FromSeconds(10); // Timeout para reintentar después de un tiempo
|
private TimeSpan _updateTimeout = TimeSpan.FromSeconds(10); // Timeout para reintentar después de un tiempo
|
||||||
|
|
||||||
|
// Añadir protección contra loops infinitos
|
||||||
|
private readonly object _updateLock = new object();
|
||||||
|
private int _concurrentUpdateCount = 0;
|
||||||
|
private const int MAX_CONCURRENT_UPDATES = 1;
|
||||||
|
private DateTime _lastUpdateAttempt = DateTime.MinValue;
|
||||||
|
private readonly TimeSpan _minUpdateInterval = TimeSpan.FromSeconds(2);
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
PlcData plcData = new PlcData();
|
PlcData plcData = new PlcData();
|
||||||
|
|
||||||
|
@ -122,6 +129,14 @@ namespace LibS7Adv
|
||||||
{
|
{
|
||||||
IsConnected = false;
|
IsConnected = false;
|
||||||
PlcData.ConnectionStatus = "offline";
|
PlcData.ConnectionStatus = "offline";
|
||||||
|
|
||||||
|
// Limpiar estado al desconectar
|
||||||
|
lock (_updateLock)
|
||||||
|
{
|
||||||
|
_isUpdating = false;
|
||||||
|
_concurrentUpdateCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
Instance = null;
|
Instance = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +147,7 @@ namespace LibS7Adv
|
||||||
_lastUpdateStartTime = DateTime.Now;
|
_lastUpdateStartTime = DateTime.Now;
|
||||||
|
|
||||||
// Actualizar cuando recibimos el evento
|
// Actualizar cuando recibimos el evento
|
||||||
UpdateTagList();
|
SafeUpdateTagList();
|
||||||
|
|
||||||
// Cuando la actualización se completa exitosamente, desactivar la bandera
|
// Cuando la actualización se completa exitosamente, desactivar la bandera
|
||||||
if (IsConfigured)
|
if (IsConfigured)
|
||||||
|
@ -141,8 +156,45 @@ namespace LibS7Adv
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Si no se pudo configurar, programar un reintento después de un tiempo
|
// Si no se pudo configurar, programar UN SOLO reintento después de un tiempo
|
||||||
Task.Delay(1000).ContinueWith(_ => UpdateTagList());
|
// Solo si no hay otra actualización en curso
|
||||||
|
lock (_updateLock)
|
||||||
|
{
|
||||||
|
if (_concurrentUpdateCount == 0)
|
||||||
|
{
|
||||||
|
Task.Delay(2000).ContinueWith(_ => SafeUpdateTagList());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SafeUpdateTagList()
|
||||||
|
{
|
||||||
|
// Verificar si podemos hacer la actualización
|
||||||
|
lock (_updateLock)
|
||||||
|
{
|
||||||
|
// No permitir más de una actualización concurrente
|
||||||
|
if (_concurrentUpdateCount >= MAX_CONCURRENT_UPDATES)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// No actualizar muy frecuentemente
|
||||||
|
if (DateTime.Now - _lastUpdateAttempt < _minUpdateInterval)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_concurrentUpdateCount++;
|
||||||
|
_lastUpdateAttempt = DateTime.Now;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
UpdateTagList();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
lock (_updateLock)
|
||||||
|
{
|
||||||
|
_concurrentUpdateCount--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,7 +234,7 @@ namespace LibS7Adv
|
||||||
if (DateTime.Now - _lastUpdateStartTime > _updateTimeout)
|
if (DateTime.Now - _lastUpdateStartTime > _updateTimeout)
|
||||||
{
|
{
|
||||||
_lastUpdateStartTime = DateTime.Now;
|
_lastUpdateStartTime = DateTime.Now;
|
||||||
UpdateTagList();
|
SafeUpdateTagList();
|
||||||
}
|
}
|
||||||
|
|
||||||
// No intentar leer durante la actualización
|
// No intentar leer durante la actualización
|
||||||
|
@ -214,8 +266,8 @@ namespace LibS7Adv
|
||||||
_isUpdating = true;
|
_isUpdating = true;
|
||||||
_lastUpdateStartTime = DateTime.Now;
|
_lastUpdateStartTime = DateTime.Now;
|
||||||
|
|
||||||
// Iniciar actualización de tags
|
// Iniciar actualización de tags de forma segura
|
||||||
Task.Run(() => UpdateTagList());
|
SafeUpdateTagList();
|
||||||
|
|
||||||
PlcData.LastError = sTag + ": Tags no actualizados, reintentando...";
|
PlcData.LastError = sTag + ": Tags no actualizados, reintentando...";
|
||||||
}
|
}
|
||||||
|
@ -245,7 +297,7 @@ namespace LibS7Adv
|
||||||
if (DateTime.Now - _lastUpdateStartTime > _updateTimeout)
|
if (DateTime.Now - _lastUpdateStartTime > _updateTimeout)
|
||||||
{
|
{
|
||||||
_lastUpdateStartTime = DateTime.Now;
|
_lastUpdateStartTime = DateTime.Now;
|
||||||
UpdateTagList();
|
SafeUpdateTagList();
|
||||||
}
|
}
|
||||||
|
|
||||||
// No intentar escribir durante la actualización
|
// No intentar escribir durante la actualización
|
||||||
|
@ -278,8 +330,8 @@ namespace LibS7Adv
|
||||||
_isUpdating = true;
|
_isUpdating = true;
|
||||||
_lastUpdateStartTime = DateTime.Now;
|
_lastUpdateStartTime = DateTime.Now;
|
||||||
|
|
||||||
// Iniciar actualización de tags
|
// Iniciar actualización de tags de forma segura
|
||||||
Task.Run(() => UpdateTagList());
|
SafeUpdateTagList();
|
||||||
|
|
||||||
PlcData.LastError = sTag + ": Tags no actualizados, reintentando...";
|
PlcData.LastError = sTag + ": Tags no actualizados, reintentando...";
|
||||||
}
|
}
|
||||||
|
@ -308,7 +360,7 @@ namespace LibS7Adv
|
||||||
if (DateTime.Now - _lastUpdateStartTime > _updateTimeout)
|
if (DateTime.Now - _lastUpdateStartTime > _updateTimeout)
|
||||||
{
|
{
|
||||||
_lastUpdateStartTime = DateTime.Now;
|
_lastUpdateStartTime = DateTime.Now;
|
||||||
UpdateTagList();
|
SafeUpdateTagList();
|
||||||
}
|
}
|
||||||
|
|
||||||
// No intentar leer durante la actualización
|
// No intentar leer durante la actualización
|
||||||
|
@ -378,8 +430,8 @@ namespace LibS7Adv
|
||||||
_isUpdating = true;
|
_isUpdating = true;
|
||||||
_lastUpdateStartTime = DateTime.Now;
|
_lastUpdateStartTime = DateTime.Now;
|
||||||
|
|
||||||
// Iniciar actualización de tags
|
// Iniciar actualización de tags de forma segura
|
||||||
Task.Run(() => UpdateTagList());
|
SafeUpdateTagList();
|
||||||
|
|
||||||
PlcData.LastError = sTag + ": Tags no actualizados, reintentando...";
|
PlcData.LastError = sTag + ": Tags no actualizados, reintentando...";
|
||||||
}
|
}
|
||||||
|
@ -404,7 +456,7 @@ namespace LibS7Adv
|
||||||
if (DateTime.Now - _lastUpdateStartTime > _updateTimeout)
|
if (DateTime.Now - _lastUpdateStartTime > _updateTimeout)
|
||||||
{
|
{
|
||||||
_lastUpdateStartTime = DateTime.Now;
|
_lastUpdateStartTime = DateTime.Now;
|
||||||
UpdateTagList();
|
SafeUpdateTagList();
|
||||||
}
|
}
|
||||||
|
|
||||||
// No intentar leer durante la actualización
|
// No intentar leer durante la actualización
|
||||||
|
@ -421,8 +473,8 @@ namespace LibS7Adv
|
||||||
_isUpdating = true;
|
_isUpdating = true;
|
||||||
_lastUpdateStartTime = DateTime.Now;
|
_lastUpdateStartTime = DateTime.Now;
|
||||||
|
|
||||||
// Iniciar actualización de tags
|
// Iniciar actualización de tags de forma segura
|
||||||
Task.Run(() => UpdateTagList());
|
SafeUpdateTagList();
|
||||||
|
|
||||||
PlcData.LastError = "Byte " + pByte + ", Bit " + pBit + ": Tags no actualizados, reintentando...";
|
PlcData.LastError = "Byte " + pByte + ", Bit " + pBit + ": Tags no actualizados, reintentando...";
|
||||||
}
|
}
|
||||||
|
@ -445,7 +497,7 @@ namespace LibS7Adv
|
||||||
if (DateTime.Now - _lastUpdateStartTime > _updateTimeout)
|
if (DateTime.Now - _lastUpdateStartTime > _updateTimeout)
|
||||||
{
|
{
|
||||||
_lastUpdateStartTime = DateTime.Now;
|
_lastUpdateStartTime = DateTime.Now;
|
||||||
UpdateTagList();
|
SafeUpdateTagList();
|
||||||
}
|
}
|
||||||
|
|
||||||
// No intentar escribir durante la actualización
|
// No intentar escribir durante la actualización
|
||||||
|
@ -462,8 +514,8 @@ namespace LibS7Adv
|
||||||
_isUpdating = true;
|
_isUpdating = true;
|
||||||
_lastUpdateStartTime = DateTime.Now;
|
_lastUpdateStartTime = DateTime.Now;
|
||||||
|
|
||||||
// Iniciar actualización de tags
|
// Iniciar actualización de tags de forma segura
|
||||||
Task.Run(() => UpdateTagList());
|
SafeUpdateTagList();
|
||||||
|
|
||||||
PlcData.LastError = "Byte " + pByte + ", Bit " + pBit + ": Tags no actualizados, reintentando...";
|
PlcData.LastError = "Byte " + pByte + ", Bit " + pBit + ": Tags no actualizados, reintentando...";
|
||||||
}
|
}
|
||||||
|
@ -491,7 +543,7 @@ namespace LibS7Adv
|
||||||
if (DateTime.Now - _lastUpdateStartTime > _updateTimeout)
|
if (DateTime.Now - _lastUpdateStartTime > _updateTimeout)
|
||||||
{
|
{
|
||||||
_lastUpdateStartTime = DateTime.Now;
|
_lastUpdateStartTime = DateTime.Now;
|
||||||
UpdateTagList();
|
SafeUpdateTagList();
|
||||||
}
|
}
|
||||||
|
|
||||||
// No intentar escribir durante la actualización
|
// No intentar escribir durante la actualización
|
||||||
|
@ -508,8 +560,8 @@ namespace LibS7Adv
|
||||||
_isUpdating = true;
|
_isUpdating = true;
|
||||||
_lastUpdateStartTime = DateTime.Now;
|
_lastUpdateStartTime = DateTime.Now;
|
||||||
|
|
||||||
// Iniciar actualización de tags
|
// Iniciar actualización de tags de forma segura
|
||||||
Task.Run(() => UpdateTagList());
|
SafeUpdateTagList();
|
||||||
|
|
||||||
PlcData.LastError = pTag + ": Tags no actualizados, reintentando...";
|
PlcData.LastError = pTag + ": Tags no actualizados, reintentando...";
|
||||||
}
|
}
|
||||||
|
@ -537,7 +589,7 @@ namespace LibS7Adv
|
||||||
if (DateTime.Now - _lastUpdateStartTime > _updateTimeout)
|
if (DateTime.Now - _lastUpdateStartTime > _updateTimeout)
|
||||||
{
|
{
|
||||||
_lastUpdateStartTime = DateTime.Now;
|
_lastUpdateStartTime = DateTime.Now;
|
||||||
UpdateTagList();
|
SafeUpdateTagList();
|
||||||
}
|
}
|
||||||
|
|
||||||
// No intentar leer durante la actualización
|
// No intentar leer durante la actualización
|
||||||
|
@ -554,8 +606,8 @@ namespace LibS7Adv
|
||||||
_isUpdating = true;
|
_isUpdating = true;
|
||||||
_lastUpdateStartTime = DateTime.Now;
|
_lastUpdateStartTime = DateTime.Now;
|
||||||
|
|
||||||
// Iniciar actualización de tags
|
// Iniciar actualización de tags de forma segura
|
||||||
Task.Run(() => UpdateTagList());
|
SafeUpdateTagList();
|
||||||
|
|
||||||
PlcData.LastError = pTag + ": Tags no actualizados, reintentando...";
|
PlcData.LastError = pTag + ": Tags no actualizados, reintentando...";
|
||||||
}
|
}
|
||||||
|
@ -584,7 +636,7 @@ namespace LibS7Adv
|
||||||
if (DateTime.Now - _lastUpdateStartTime > _updateTimeout)
|
if (DateTime.Now - _lastUpdateStartTime > _updateTimeout)
|
||||||
{
|
{
|
||||||
_lastUpdateStartTime = DateTime.Now;
|
_lastUpdateStartTime = DateTime.Now;
|
||||||
UpdateTagList();
|
SafeUpdateTagList();
|
||||||
}
|
}
|
||||||
|
|
||||||
// No intentar escribir durante la actualización
|
// No intentar escribir durante la actualización
|
||||||
|
@ -601,8 +653,8 @@ namespace LibS7Adv
|
||||||
_isUpdating = true;
|
_isUpdating = true;
|
||||||
_lastUpdateStartTime = DateTime.Now;
|
_lastUpdateStartTime = DateTime.Now;
|
||||||
|
|
||||||
// Iniciar actualización de tags
|
// Iniciar actualización de tags de forma segura
|
||||||
Task.Run(() => UpdateTagList());
|
SafeUpdateTagList();
|
||||||
|
|
||||||
PlcData.LastError = pTag + ": Tags no actualizados, reintentando...";
|
PlcData.LastError = pTag + ": Tags no actualizados, reintentando...";
|
||||||
}
|
}
|
||||||
|
@ -629,7 +681,7 @@ namespace LibS7Adv
|
||||||
if (DateTime.Now - _lastUpdateStartTime > _updateTimeout)
|
if (DateTime.Now - _lastUpdateStartTime > _updateTimeout)
|
||||||
{
|
{
|
||||||
_lastUpdateStartTime = DateTime.Now;
|
_lastUpdateStartTime = DateTime.Now;
|
||||||
UpdateTagList();
|
SafeUpdateTagList();
|
||||||
}
|
}
|
||||||
|
|
||||||
// No intentar escribir durante la actualización
|
// No intentar escribir durante la actualización
|
||||||
|
@ -646,8 +698,8 @@ namespace LibS7Adv
|
||||||
_isUpdating = true;
|
_isUpdating = true;
|
||||||
_lastUpdateStartTime = DateTime.Now;
|
_lastUpdateStartTime = DateTime.Now;
|
||||||
|
|
||||||
// Iniciar actualización de tags
|
// Iniciar actualización de tags de forma segura
|
||||||
Task.Run(() => UpdateTagList());
|
SafeUpdateTagList();
|
||||||
|
|
||||||
PlcData.LastError = pTag + ": Tags no actualizados, reintentando...";
|
PlcData.LastError = pTag + ": Tags no actualizados, reintentando...";
|
||||||
}
|
}
|
||||||
|
@ -675,7 +727,7 @@ namespace LibS7Adv
|
||||||
if (DateTime.Now - _lastUpdateStartTime > _updateTimeout)
|
if (DateTime.Now - _lastUpdateStartTime > _updateTimeout)
|
||||||
{
|
{
|
||||||
_lastUpdateStartTime = DateTime.Now;
|
_lastUpdateStartTime = DateTime.Now;
|
||||||
UpdateTagList();
|
SafeUpdateTagList();
|
||||||
}
|
}
|
||||||
|
|
||||||
// No intentar leer durante la actualización
|
// No intentar leer durante la actualización
|
||||||
|
@ -693,8 +745,8 @@ namespace LibS7Adv
|
||||||
_isUpdating = true;
|
_isUpdating = true;
|
||||||
_lastUpdateStartTime = DateTime.Now;
|
_lastUpdateStartTime = DateTime.Now;
|
||||||
|
|
||||||
// Iniciar actualización de tags
|
// Iniciar actualización de tags de forma segura
|
||||||
Task.Run(() => UpdateTagList());
|
SafeUpdateTagList();
|
||||||
|
|
||||||
PlcData.LastError = pTag + ": Tags no actualizados, reintentando...";
|
PlcData.LastError = pTag + ": Tags no actualizados, reintentando...";
|
||||||
}
|
}
|
||||||
|
@ -723,7 +775,7 @@ namespace LibS7Adv
|
||||||
if (DateTime.Now - _lastUpdateStartTime > _updateTimeout)
|
if (DateTime.Now - _lastUpdateStartTime > _updateTimeout)
|
||||||
{
|
{
|
||||||
_lastUpdateStartTime = DateTime.Now;
|
_lastUpdateStartTime = DateTime.Now;
|
||||||
UpdateTagList();
|
SafeUpdateTagList();
|
||||||
}
|
}
|
||||||
|
|
||||||
// No intentar leer durante la actualización
|
// No intentar leer durante la actualización
|
||||||
|
@ -741,8 +793,8 @@ namespace LibS7Adv
|
||||||
_isUpdating = true;
|
_isUpdating = true;
|
||||||
_lastUpdateStartTime = DateTime.Now;
|
_lastUpdateStartTime = DateTime.Now;
|
||||||
|
|
||||||
// Iniciar actualización de tags
|
// Iniciar actualización de tags de forma segura
|
||||||
Task.Run(() => UpdateTagList());
|
SafeUpdateTagList();
|
||||||
|
|
||||||
PlcData.LastError = pTag + ": Tags no actualizados, reintentando...";
|
PlcData.LastError = pTag + ": Tags no actualizados, reintentando...";
|
||||||
}
|
}
|
||||||
|
@ -771,7 +823,7 @@ namespace LibS7Adv
|
||||||
if (DateTime.Now - _lastUpdateStartTime > _updateTimeout)
|
if (DateTime.Now - _lastUpdateStartTime > _updateTimeout)
|
||||||
{
|
{
|
||||||
_lastUpdateStartTime = DateTime.Now;
|
_lastUpdateStartTime = DateTime.Now;
|
||||||
UpdateTagList();
|
SafeUpdateTagList();
|
||||||
}
|
}
|
||||||
|
|
||||||
// No intentar leer durante la actualización
|
// No intentar leer durante la actualización
|
||||||
|
@ -789,8 +841,8 @@ namespace LibS7Adv
|
||||||
_isUpdating = true;
|
_isUpdating = true;
|
||||||
_lastUpdateStartTime = DateTime.Now;
|
_lastUpdateStartTime = DateTime.Now;
|
||||||
|
|
||||||
// Iniciar actualización de tags
|
// Iniciar actualización de tags de forma segura
|
||||||
Task.Run(() => UpdateTagList());
|
SafeUpdateTagList();
|
||||||
|
|
||||||
PlcData.LastError = pTag + ": Tags no actualizados, reintentando...";
|
PlcData.LastError = pTag + ": Tags no actualizados, reintentando...";
|
||||||
}
|
}
|
||||||
|
@ -819,7 +871,7 @@ namespace LibS7Adv
|
||||||
if (DateTime.Now - _lastUpdateStartTime > _updateTimeout)
|
if (DateTime.Now - _lastUpdateStartTime > _updateTimeout)
|
||||||
{
|
{
|
||||||
_lastUpdateStartTime = DateTime.Now;
|
_lastUpdateStartTime = DateTime.Now;
|
||||||
UpdateTagList();
|
SafeUpdateTagList();
|
||||||
}
|
}
|
||||||
|
|
||||||
// No intentar escribir durante la actualización
|
// No intentar escribir durante la actualización
|
||||||
|
@ -836,8 +888,8 @@ namespace LibS7Adv
|
||||||
_isUpdating = true;
|
_isUpdating = true;
|
||||||
_lastUpdateStartTime = DateTime.Now;
|
_lastUpdateStartTime = DateTime.Now;
|
||||||
|
|
||||||
// Iniciar actualización de tags
|
// Iniciar actualización de tags de forma segura
|
||||||
Task.Run(() => UpdateTagList());
|
SafeUpdateTagList();
|
||||||
|
|
||||||
PlcData.LastError = pTag + ": Tags no actualizados, reintentando...";
|
PlcData.LastError = pTag + ": Tags no actualizados, reintentando...";
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue