public IReadonlySignal GetSignal(string id)
        {
            lock (mProcessingLock)
            {
                Console.WriteLine("->> IReadonlySignal GetSignal");
                ReadolnySignal rv;
                mVerifiedSignals.TryGetValue(id, out rv);

                if (rv == null)
                {
                    if (mIsSignalsLoad)
                    {
                        Console.WriteLine("WARNING! Signal \"{0}\" not applicable", id);
                    }

                    // если мы еще не успели загрузить список сигналов - добавить mockup, позже загрузим реальную спецификацию
                    // если уже загрузили и его нет в списке - ничего страшного, он просто не будет обновляться
                    mUnchekedSignals.TryGetValue(id, out rv);
                    if (rv != null)
                    {
                        Console.WriteLine("t<<< GetSignal rv != null");
                        return(rv);
                    }

                    rv = new ReadolnySignal(id);
                    mUnchekedSignals.Add(id, rv);
                }
                else
                {
                    // добавляем в список для запроса состояния
                    if (!mSubscribedSignals.Contains(id))
                    {
                        mSubscribedSignals.Add(id);
                    }
                }

                //Console.WriteLine("\t<<- GetSignal");
                return(rv);
            }
        }
        private void Processing()
        {
            //mJournal.Info("RemoteSignalsFactory started");
            Console.WriteLine("RemoteSignalsFactory started");
            try
            {
                var lastUpdate = DateTime.MinValue;
                while (true)
                {
                    try
                    {
                        if (DateTime.Now.Subtract(lastUpdate).TotalMilliseconds < mUpdateTimeout)
                        {
                            Thread.Sleep(200);
                            continue;
                        }


                        // пробуем получить список сигналов
                        if (!mIsSignalsLoad)
                        {
                            lock (mProcessingLock)
                            {
                                var specs = mRemoteClient.GetSignals();
                                if (specs != null)
                                {
                                    mIsSignalsLoad = true;
                                    foreach (var spec in specs.Specs)
                                    {
                                        ReadolnySignal rv;
                                        if (mUnchekedSignals.ContainsKey(spec.Id))
                                        {
                                            mUnchekedSignals.TryGetValue(spec.Id, out rv);
                                            if (rv == null)
                                            {
                                                continue;
                                            }

                                            rv.UpdateSpecification(spec);       // обновляем спецификацию
                                            mVerifiedSignals.Add(spec.Id, rv);  // добавляем в список верифицированных сигналов
                                            mSubscribedSignals.Add(spec.Id);    // поскольку его уже запрашивали и он верифицирован, то добавляем в подписку на обновление
                                        }
                                        else
                                        {
                                            rv = new ReadolnySignal(spec);
                                            mVerifiedSignals.Add(spec.Id, rv); // чистый сигнал, который никто не спрашивал
                                        }

                                        rv.Update(new SignalStatus {
                                            LastUpdate = spec.SaveAt, Value = spec.Value
                                        });
                                    }

                                    if (OnLoad != null)
                                    {
                                        OnLoad();
                                    }
                                }
                            }
                        }
                        else
                        {
                            if (mSubscribedSignals.Count == 0)
                            {
                                lastUpdate = DateTime.Now;
                                continue;
                            }

                            // если есть списки, то пробуем обновляться по подписанным сигналам
                            lock (mProcessingLock)
                            {
                                var rv = mRemoteClient.GetStatus(new SignalsRequest(mSubscribedSignals));

                                if (rv != null)
                                {
                                    for (var i = 0; i < mSubscribedSignals.Count; i++)
                                    {
                                        ReadolnySignal signal;
                                        mVerifiedSignals.TryGetValue(mSubscribedSignals[i], out signal);

                                        if (signal != null)
                                        {
                                            signal.Update(rv.Signals[i]);
                                            if (signal.Specification.Id == "local.tank.level")
                                            {
                                                Console.WriteLine("RemoteSignalsFactory TEST SIGNAL");
                                            }
                                            Console.WriteLine("{0}: local.tank.level: {1}", DateTime.Now.ToString("HH:mm:ss.fff"), signal.Value);
                                        }
                                    }

                                    if (OnUpdate != null)
                                    {
                                        OnUpdate();
                                    }
                                }
                            }
                        }

                        lastUpdate = DateTime.Now;
                    }
                    catch (Exception ex)
                    {
                        //mJournal.Fatal(ex);
                        Console.WriteLine(ex);
                    }
                }
            }
            catch (ThreadAbortException)
            {
                mRemoteClient.Dispose();
                Console.WriteLine("RemoteSignalsFactory stopped thread abort exception");
                //mJournal.Info("RemoteSignalsFactory stopped");
            }
        }