Я сообщил об этой проблеме создателям пакета nuget.
Ответ 6.3.2020:
Спасибо за сообщение об этой проблеме, это важный аспект. Я кратко изучил ваше дело. К сожалению, автоматическое c воскрешение наблюдаемого на самом деле не поддерживается. Причина в том, что PollValues внутренне использует дескрипторы Symbol, которые будут недействительными при обновлении программы PL C. Поэтому на самом деле ваше единственное решение - зарегистрироваться для события SymbolVersionChanged в TcAdsClient / AdsConnection (отправляется после загрузки / перезапуска) и воссоздать Observable.
https://infosys.beckhoff.de/content/1031/tc3_adsnetref/7313543307.html?id=2192955395989567903
Если вам целесообразно дождаться следующей версии пакета AdsClient / Ads.Reactive - должна быть возможность обработать эту ситуацию внутренне в коде PollValues (так, как вы ожидаете). Теперь он есть в моем списке TODO.
Прежде чем я получил этот ответ, я отредактировал их реализацию и создал свой собственный метод расширения.
Реализация TwinCAT.Ads.Reactive v4.4.0
public static IObservable<T> PollValues<T>(
this IAdsConnection connection,
string instancePath,
int[] args,
IObservable<Unit> trigger,
Func<Exception, T> errorHandler)
{
DisposableHandleBag bag = new DisposableHandleBag(connection, (IList<string>) new string[1]
{
instancePath
});
Func<Unit, T> selector = (Func<Unit, T>) (o =>
{
try
{
return (T) connection.ReadAny(61445U, bag.GetHandle(instancePath), typeof (T), args);
}
catch (Exception ex)
{
if (errorHandler != null)
return errorHandler(ex);
throw;
}
});
Action finallyAction = (Action) (() =>
{
bag.Dispose();
bag = (DisposableHandleBag) null;
});
return trigger.Select<Unit, T>(selector).Finally<T>(finallyAction);
}
Мое редактирование - где я создаю дескриптор для каждого дескриптора чтения и удаления после чтения
public static IObservable<T> MyPollValues<T>(
this IAdsConnection connection,
string instancePath,
int[] args,
IObservable<Unit> trigger,
Func<Exception, T> errorHandler)
{
Func<Unit, T> selector = (Func<Unit, T>)(o =>
{
try
{
var handle = connection.CreateVariableHandle(instancePath);
var data = (T)connection.ReadAny(handle, typeof(T), args);
connection.DeleteVariableHandle(handle);
return data;
}
catch (Exception ex)
{
if (errorHandler != null)
return errorHandler(ex);
throw;
}
});
return trigger.Select<Unit, T>(selector);
}