/// <summary> /// No throw. Returns null or changed clientObjs (not null, but possibly zero-lenghth). /// </summary> public object[]? PollChanges() { if (XiList is null || XiList.Disposed) { return(null); } if (XiList.Pollable) { try { var changedClientObjs = new List <object>(); IXiDataListItem[] changedXiDataListItems = XiList.PollDataChanges(); foreach (IXiDataListItem xiDataListItem in changedXiDataListItems) { var o = xiDataListItem.Obj as XiListItemWrapper; if (o is null) { throw new InvalidOperationException(); } foreach (var modelItem in o.ClientObjectInfosCollection) { if (modelItem.ClientObj is not null) { changedClientObjs.Add(modelItem.ClientObj); } } } return(changedClientObjs.ToArray()); } catch { } } return(null); }
/// <summary> /// Invokes XiList.PollDataChanges() if XiList Pollable and not Callbackable. /// No throw. /// </summary> public void PollChangesIfNotCallbackable() { if (XiList is null || XiList.Disposed) { return; } if (XiList.Pollable && !XiList.Callbackable) { try { XiList.PollDataChanges(); } catch { } } }
public void Write(object clientObj, ValueStatusTimestamp valueStatusTimestamp) { if (XiList is null || XiList.Disposed) { return; } ClientObjectInfo?modelItem; if (!ClientObjectInfosDictionary.TryGetValue(clientObj, out modelItem)) { return; } if (modelItem.XiListItemWrapper is null || modelItem.XiListItemWrapper.XiListItem is null || modelItem.XiListItemWrapper.XiListItem.ResultCode != XiFaultCodes.S_OK) { return; } IXiDataListItem xiDataListItem = modelItem.XiListItemWrapper.XiListItem; try { xiDataListItem.PrepareForWrite(valueStatusTimestamp); try { XiList.CommitWriteDataListItems(); } catch { } } catch (Exception ex) { Logger?.LogWarning(ex, "Exception"); } }
/// <summary> /// Creates List, adds/removes items. /// No throw. /// </summary> public void Subscribe(XiServerProxy xiServerProxy) { try { if (!XiItemsMustBeAddedOrRemoved) { return; } bool firstTimeDataJournalConnection = (XiList is null); if (firstTimeDataJournalConnection) { try { if (xiServerProxy.ContextExists) { XiList = xiServerProxy.NewDataJournalList(0, 0, null); } } catch (Exception) { } } if (XiList is null || XiList.Disposed) { return; } bool connectionError = SubscribeInitial(); try { if (!connectionError && XiList is not null && !XiList.Disposed) { if (firstTimeDataJournalConnection) { try { XiList.Readable = true; } catch { } } XiList.EnableListUpdating(true); } } catch (Exception ex) { Logger?.LogWarning(ex, "Exception"); connectionError = true; } if (!connectionError) { XiItemsMustBeAddedOrRemoved = false; } } finally { SubscribeFinal(); } }
/// <summary> /// Returns clientObjs whose write failed. /// If connection error, no throw and returns all clientObjs. /// </summary> /// <param name="clientObjs"></param> /// <param name="valueStatusTimestamps"></param> /// <returns></returns> public object[] Write(object[] clientObjs, ValueStatusTimestamp[] valueStatusTimestamps) { if (XiList is null || XiList.Disposed) { return(clientObjs); } int i = -1; var result = new List <object>(); foreach (var clientObj in clientObjs) { i++; ClientObjectInfo?modelItem; if (!ClientObjectInfosDictionary.TryGetValue(clientObj, out modelItem)) { result.Add(clientObj); continue; } if (modelItem.XiListItemWrapper is null || modelItem.XiListItemWrapper.XiListItem is null || modelItem.XiListItemWrapper.XiListItem.ResultCode != XiFaultCodes.S_OK) { result.Add(clientObj); continue; } IXiDataListItem xiDataListItem = modelItem.XiListItemWrapper.XiListItem; xiDataListItem.PrepareForWrite(valueStatusTimestamps[i]); } IEnumerable <IXiDataListItem>?failedItems = null; try { failedItems = XiList.CommitWriteDataListItems(); } catch { return(clientObjs); } if (failedItems is not null) { foreach (var xiDataListItem in failedItems) { var o = xiDataListItem.Obj as XiListItemWrapper; if (o is null) { throw new InvalidOperationException(); } foreach (var modelItem in o.ClientObjectInfosCollection) { if (modelItem.ClientObj is not null) { result.Add(modelItem.ClientObj); } } } } return(result.ToArray()); }
/// <summary> /// Creates List, adds/removes items. /// No throw. /// </summary> /// <param name="xiServerProxy"></param> /// <param name="сallbackDoer"></param> /// <param name="elementValuesCallbackEventHandler"></param> /// <param name="callbackable"></param> /// <param name="ct"></param> public void Subscribe(XiServerProxy xiServerProxy, IDispatcher?сallbackDoer, ElementValuesCallbackEventHandler elementValuesCallbackEventHandler, bool callbackable, CancellationToken ct) { try { if (ct.IsCancellationRequested) { return; } if (!XiItemsMustBeAddedOrRemoved) { return; } bool firstTimeDataConnection = (XiList is null); if (firstTimeDataConnection) { try { if (xiServerProxy.ContextExists) { XiList = xiServerProxy.NewDataList(0, 0, null); } } catch (Exception) { } } bool connectionError = SubscribeInitial(); try { if (!connectionError && XiList is not null && !XiList.Disposed) { if (firstTimeDataConnection) { XiList.ElementValuesCallback += (IXiDataListProxy dataList, IXiDataListItem[] items, ValueStatusTimestamp[] values) => { var changedClientObjs = new List <object>(items.Length); var changedValues = new List <ValueStatusTimestamp>(items.Length); int i = 0; foreach (IXiDataListItem xiDataListItem in items) { var o = xiDataListItem.Obj as XiListItemWrapper; if (o is null) { throw new InvalidOperationException(); } foreach (var modelItem in o.ClientObjectInfosCollection) { modelItem.ForceNotifyClientObj = false; if (modelItem.ClientObj is not null) { changedClientObjs.Add(modelItem.ClientObj); changedValues.Add(values[i]); } } i++; } if (ct.IsCancellationRequested) { return; } Logger?.LogDebug("XiList.ElementValuesCallback"); if (сallbackDoer is not null) { try { сallbackDoer.BeginInvoke(ct => { Logger?.LogDebug("XiList.ElementValuesCallback dispatched"); elementValuesCallbackEventHandler(changedClientObjs.ToArray(), changedValues.ToArray()); }); } catch (Exception) { } } }; if (callbackable) { try { XiList.Callbackable = true; } catch { } } try { XiList.Pollable = true; } catch { } try { XiList.Readable = true; } catch { } try { XiList.Writeable = true; } catch { } XiList.EnableListUpdating(true); } XiList.EnableListElementUpdating(true, null); } } catch (Exception ex) { Logger?.LogWarning(ex, "Exception"); connectionError = true; } { var utcNow = DateTime.UtcNow; var changedClientObjs = new List <object>(); var changedValues = new List <ValueStatusTimestamp>(); foreach (XiListItemWrapper xiListItemWrapper in XiListItemWrappersDictionary.Values) { foreach (var modelItem in xiListItemWrapper.ClientObjectInfosCollection) { if (modelItem.ForceNotifyClientObj) { modelItem.ForceNotifyClientObj = false; if (modelItem.ClientObj is not null) { if (xiListItemWrapper.ItemDoesNotExist) { changedClientObjs.Add(modelItem.ClientObj); changedValues.Add(new ValueStatusTimestamp { ValueStatusCode = ValueStatusCode.ItemDoesNotExist }); } else if (xiListItemWrapper.XiListItem is not null) { changedClientObjs.Add(modelItem.ClientObj); changedValues.Add(xiListItemWrapper.XiListItem.ValueStatusTimestamp); } else { changedClientObjs.Add(modelItem.ClientObj); changedValues.Add(new ValueStatusTimestamp(new Any(), ValueStatusCode.Unknown, utcNow)); } } } } } if (changedClientObjs.Count > 0) { if (ct.IsCancellationRequested) { return; } if (сallbackDoer is not null) { try { сallbackDoer.BeginInvoke(ct => elementValuesCallbackEventHandler(changedClientObjs.ToArray(), changedValues.ToArray())); } catch (Exception) { } } } } if (!connectionError) { XiItemsMustBeAddedOrRemoved = false; } } finally { SubscribeFinal(); } }