private EnumError WriteData(System.IO.TextReader indata, System.IO.TextWriter outdata,out TimeSpan tstime)
        {
            TimerUtil tuse = new TimerUtil();
            tstime = new TimeSpan();
            try
            {
                    ConsoleLogger.LogMessage("WriteData() " + this.GetType().ToString());
                    tuse.MarkInterval();
                    int cnttest = 0;
                    if (int.TryParse(indata.ReadLine(), out cnttest) == false)
                    {
                        return EnumError.InvalidInputData;
                    }

                    if (cnttest > 0)
                    {
                        for (int i = 1; i <= cnttest; i++)
                        {
            #if VERBOSE
                            if (((i * 100.0) / cnttest) % 10 == 0) ConsoleLogger.LogMessage("Writed: " + i.ToString() + " / " + cnttest.ToString());
            #endif
                            if (i > 1)
                            {
                                outdata.WriteLine("");
                            }
                            //
                            string curprefix = indata.ReadLine();
                            List<String> autocompletewords = GetPrefixWords(curprefix);
                            if (autocompletewords != null)
                            {
                                foreach (string str in autocompletewords)
                                {
                                    outdata.WriteLine(str);
                                }
                            }
                            mrenewData.Set();
                        }
                    }
                    return EnumError.NoError;
            }
            catch (Exception ex)
            {
                ConsoleLogger.LogMessage(ex.Message);
                return EnumError.Exception;
            }
            finally
            {
                tuse.MarkInterval();
                tstime = tuse.GetLastIntervalTime();

                ConsoleLogger.LogMessage(String.Format("TC: use: {0:S} compare: {1:D}",
                    tuse.GetLastIntervalTime().ToString(),
                    WordItem.CompareCallCnt
                    ));
            }

            return EnumError.Unknown_Error;
        }
        /// <summary>
        /// Метод читает данные из потока, строит словарь, читает проверочные данные и записывает их в выходной поток 
        /// </summary>
        protected EnumError DoBuildAndUse(System.IO.TextReader indata, System.IO.TextWriter outdata)
        {
            TimerUtil tall = new TimerUtil();
            TimeSpan tsbuild = new TimeSpan();
            TimeSpan tsuse = new TimeSpan();
            EnumError result = EnumError.Unknown_Error;
            if (indata == null) return EnumError.InvalidInputData;
            if (outdata == null) return EnumError.InvalidInputData;

            try
            {
                //Читаем из потока данные для построения префиксного словаря
                result=BuildData(indata, out tsbuild);

                //Если при построении префиксного словаря произошла ошибка выходим из функции.
                if (result != EnumError.NoError)
                {
                    return result;
                }

                //Продолжаем читать из потока данные для поиска префиксов и вывода TopN слов из словаря
                result=WriteData(indata,outdata,out tsuse);

                return result;
            }
            catch (Exception ex)
            {
                ConsoleLogger.LogMessage(ex.ToString());
                return EnumError.Exception;
            }
            finally
            {
                tall.MarkInterval();

                if (indata != null) { indata.Close(); };
                if (outdata != null) { outdata.Close(); };

                ConsoleLogger.LogMessage("All Done");
                ConsoleLogger.LogMessage(String.Format("TC: all {0:S} build: {1:S} use {2:S}, compare: {3:D}",
                    tall.GetLastIntervalTime().ToString(),
                    tsbuild.ToString(),
                    tsuse.ToString(),
                    WordItem.CompareCallCnt
                    ));

            }

            return EnumError.Unknown_Error;
        }
        private EnumError BuildData(System.IO.TextReader indata, out TimeSpan tstime)
        {
            TimerUtil tbuild = new TimerUtil();
            tstime = new TimeSpan();
            try
            {
                ConsoleLogger.LogMessage("BuildData() " + this.GetType().ToString());
                if (indata == null)
                {
                    throw new NullReferenceException("indata stream is null");
                }

                int cnt = 0;
                if (int.TryParse(indata.ReadLine(), out cnt) == false)
                {
                    ConsoleLogger.LogMessage("Cant parse dict cnt");
                    return EnumError.InvalidInputData;
                }

                //Проверка кол-во входных слов
                if (cnt < 0 || cnt > MaxInWords)
                {
                    ConsoleLogger.LogMessage("Wrong dict cnt " + cnt);
                    return EnumError.InvalidInputData;
                }

                ConsoleLogger.LogMessage("Uses DicCnt: " + cnt.ToString());

                this.DicCnt = cnt;

                for (int i = 1; i <= this.DicCnt; i++)
                {
            #if VERBOSE
                        if (((i * 100.0) / this.DicCnt) % 10 == 0) ConsoleLogger.LogMessage("Readed: " + i.ToString() + " / " + this.DicCnt.ToString());
            #endif
                    String wline = indata.ReadLine();
                    if (wline == null)
                    {
                        ConsoleLogger.LogMessage("Unexpected end of data");
                        return EnumError.InvalidInputData;
                    }
                    string[] items = wline.Split(' ');
                    if (items.Length == 2)
                    {
                        this.AddNewDictItem(items[0], int.Parse(items[1]));
                    }
                    else
                    {
                        ConsoleLogger.LogMessage("Wrong line: " + wline);
                        //throw new Exception("Wrong line: " + wline);
                        return EnumError.InvalidInputData;
                    }
                }
                AfterAllRead();
                return EnumError.NoError;
            }
            catch (Exception ex)
            {
                ConsoleLogger.LogMessage(ex.ToString());
                return EnumError.Exception;
            }
            finally
            {
                tbuild.MarkInterval();
                tstime = tbuild.GetLastIntervalTime();

                ConsoleLogger.LogMessage(String.Format("TC: build: {0:S} compare: {1:D}",
                    tbuild.GetLastIntervalTime().ToString(),
                    WordItem.CompareCallCnt
                    ));
            }

            return EnumError.Unknown_Error;
        }
        public void DoLoop()
        {
            TimerUtil tu = new TimerUtil();
            TimerUtil tcReadWrite = new TimerUtil();
            tcReadWrite.Stop();
            tcReadWrite.Reset();

            try
            {

                Thread thrReadStream_WriteConsole = new Thread(new ThreadStart(ReadStream_WriteConsole));
                Thread thrReadConsole_WriteStream = new Thread(new ThreadStart(ReadConsole_WriteStream));

                TcpClient client = new TcpClient(hostname, port);
                client.NoDelay = true;

                stream = client.GetStream();

                tcReadWrite.MarkInterval();

                //запускаем потоки
                thrReadStream_WriteConsole.Start();
                thrReadConsole_WriteStream.Start();

                WaitHandle[] wh = new WaitHandle[]
                    {
                        mreServerEndData
                    };
                WaitHandle.WaitAll(wh);
                //server ends data abort thrReadConsoleWriteStream and wait for thrReadStreamWriteConsole
                //thrReadConsole_WriteStream.Abort(); this not work, see http://stackoverflow.com/questions/9479573/interrupt-console-readline

                thrReadStream_WriteConsole.Join();
                thrReadConsole_WriteStream.Join();
            #if VERBOSE

                ConsoleLogger.LogMessage("WaitHandle.WaitAll(wh); exit");
            #endif
            }
            catch (Exception ex)
            {
                ConsoleLogger.LogMessage("Error in DoLoop: "+ex.Message);
            }finally
            {
                ConsoleLogger.LogMessage("TC:" + tu.GetInterval() + " TCReadWrite: " + tcReadWrite.GetInterval());
            }
        }