/// <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();
            }
        }
        /// <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>
        ///     No throw.
        /// </summary>
        /// <param name="xiServerProxy"></param>
        /// <param name="сallbackDoer"></param>
        /// <param name="callbackable"></param>
        /// <param name="ct"></param>
        public void Subscribe(XiServerProxy xiServerProxy, IDispatcher?сallbackDoer, bool callbackable, CancellationToken ct)
        {
            if (ct.IsCancellationRequested)
            {
                return;
            }
            if (!xiServerProxy.ContextExists)
            {
                return;
            }
            if (!_xiEventItemsMustBeAdded)
            {
                return;
            }

            bool allOk = true;

            foreach (
                var kvp in _eventMessagesCallbackEventHandlers)
            {
                if (ct.IsCancellationRequested)
                {
                    return;
                }
                if (kvp.Value.P is not null)
                {
                    continue;
                }

                var f       = new List <ORedFilters>();
                var filters = new FilterSet
                {
                    Filters = f
                };
                var fc = new List <FilterCriterion>();
                f.Add(new ORedFilters
                {
                    FilterCriteria = fc
                });
                fc.Add(new FilterCriterion
                {
                    Operator        = 1, //Eq
                    ComparisonValue =
                        XiSystem,
                    OperandName = "Area"
                });

                IXiEventListProxy xiEventList;

                try
                {
                    xiEventList = xiServerProxy.NewEventList(0, 0, filters);
                }
                catch (Exception)
                {
                    return;
                }

                try
                {
                    if (xiEventList.Disposed)
                    {
                        return;
                    }

                    try
                    {
                        Action <Ssz.Utils.DataAccess.EventMessage[]> eventMessagesCallbackEventHandler = kvp.Key;

                        xiEventList.EventMessagesCallbackEvent +=
                            (IXiEventListProxy eventList, IEnumerable <IXiEventListItem> newListItems) =>
                        {
                            if (ct.IsCancellationRequested)
                            {
                                return;
                            }
                            if (сallbackDoer is not null)
                            {
                                try
                                {
                                    сallbackDoer.BeginInvoke(ct => eventMessagesCallbackEventHandler(
                                                                 newListItems.Select(li => li.EventMessage).ToArray()));
                                }
                                catch (Exception)
                                {
                                }
                            }
                        };

                        if (callbackable)
                        {
                            try
                            {
                                xiEventList.Callbackable = true;
                            }
                            catch
                            {
                            }
                        }
                        try
                        {
                            xiEventList.Pollable = true;
                        }
                        catch
                        {
                        }
                        try
                        {
                            xiEventList.Writeable = true;
                        }
                        catch
                        {
                        }

                        xiEventList.EnableListUpdating(true);
                    }
                    catch (Exception)
                    {
                        allOk = false;
                    }
                }
                catch
                {
                    //Logger?.LogWarning(ex);
                }

                kvp.Value.P = xiEventList;

                if (allOk)
                {
                    _xiEventItemsMustBeAdded = false;
                }
            }
        }