Пример #1
0
        /// <summary>
        /// Обрабатывает в фоновом потоке входной запрос
        /// </summary>
        /// <param name="StateInfo"></param>
        void RequestProcessing(Object objectState)
        {
            TaskInfo ti = (TaskInfo)objectState;

            Log($"Процесс {Thread.CurrentThread.ManagedThreadId} запущен");

            InternalContext cntx;

            try
            {
                while (true)
                {
                    if (Canceling)
                    {
                        Log("Обработчик запросов {0} остановлен", Thread.CurrentThread.ManagedThreadId);
                        ti.Cancel();
                        return;
                    }

                    if (Conveyor.TryTake(out cntx))
                    {
                        if (cntx == null)
                        {
                            continue;
                        }

                        if (cntx.RunCollect)
                        {
                            // Log("Запуск сборщика мусора для MaxGeneration={0}", GC.MaxGeneration);
                            // GC.Collect(GC.MaxGeneration > 1 ? GC.MaxGeneration - 1 : GC.MaxGeneration, GCCollectionMode.Forced);
                            // GC.Collect();
                            continue;
                        }

                        lock (SyncLock)
                        {
                            processes++;
                            if (processes > maxprocesses)
                            {
                                maxprocesses = processes;
                            }
                            if (cnt == 50)
                            {
                                double pag = (double)System.Diagnostics.Process.GetCurrentProcess().PagedMemorySize64 / 1048576.0;
                                double vir = (double)System.Diagnostics.Process.GetCurrentProcess().VirtualMemorySize64 / 1048576.0;
                                double mem = (double)System.Diagnostics.Process.GetCurrentProcess().WorkingSet64 / 1048576.0;
                                Log("Memory={0}Mb Paged={1}Mb, Vitualr={2}Mb processed {3} max {4}",
                                    mem.ToString("#,###.##"), pag.ToString("#,###.##"), vir.ToString("#,###.##"), processes + Redo.processes, maxprocesses + Redo.maxprocesses);
                                cnt = 0;
                            }
                            else
                            {
                                cnt++;
                            }
                        }

                        // Загрузим сертификат клиента, если он есть.
                        if (cntx.context.Request.IsSecureConnection)
                        {
                            cntx.ri.GetClientCertificate();
                            Log("{0}", Properties.Resources.clientCertificateReceived);
                        }

                        // Получим кодировку клиента
                        cntx.ri.ClientEncoding = cntx.context.Request.ContentEncoding ?? Encoding.GetEncoding(1251);

                        // Читаем запрос
                        cntx.ri.stRequest = DecompressRead(cntx);

                        // Экземпляр конвейера запроса
                        using (Processing processing = new Processing(cntx.ri, m_LogFile))
                            // По завершении выполнения будет отправлен ответ на входной запрос
                            processing.Run();
                    }

                    // Дадим возможность выполнятся другим процессам
                    Thread.Sleep(100);
                }
            }
            catch (Exception ex)
            {
                Log("{0}\r\n{1}", ex.Message, ex.StackTrace);
            }
        }
Пример #2
0
        /// <summary>
        /// Основной цикл ожидания
        /// </summary>
        public void Run()
        {
            // Обрабатывать Ctrl-C как обычный ввод
            Console.TreatControlCAsInput = true;

            processes    = 0;
            maxprocesses = 0;

            Task task;

            ManualResetEvent[] me = new ManualResetEvent[Settings.ConveyorSize];

            // Запуск конвеера
            Conveyor = new ConcurrentBag <InternalContext>();

            // Запуск слушателя
            try
            {
                Start();
            }
            catch (HttpListenerException ex)
            {
                Log("{0} Code={1} in {2}\r\n{3}", ex.Message, ex.ErrorCode, ex.Source, ex.StackTrace);
                Console.WriteLine("{0} Code={1} in {2}\r\n{3}", ex.Message, ex.ErrorCode, ex.Source, ex.StackTrace);
                if (ex.InnerException != null)
                {
                    Log("Оригинал: {0}\r\n{1}", ex.InnerException.Message, ex.InnerException.StackTrace);
                    Console.WriteLine("Оригинал: {0}\r\n{1}", ex.InnerException.Message, ex.InnerException.StackTrace);
                }
                if (ex.Data != null)
                {
                    Console.WriteLine("  Extra details:");
                    foreach (DictionaryEntry de in ex.Data)
                    {
                        Console.WriteLine("    The key is '{0}' and the value is: {1}", de.Key, de.Value);
                    }
                }
                Redo.Canceling          = true;
                GWMtsRegister.Canceling = true;
                return;
            }

            for (int i = 0; i < Settings.ConveyorSize; i++)
            {
                me[i] = new ManualResetEvent(false);
                TaskInfo ti = new TaskInfo(me[i]);
                task = new Task(RequestProcessing, ti, TaskCreationOptions.LongRunning | TaskCreationOptions.AttachedToParent | TaskCreationOptions.PreferFairness);
                task.Start();
            }
            Log("Запущено {0} процессов конвейера", Settings.ConveyorSize);

            // Запускаем первый запрос
            m_HttpListener.BeginGetContext(new AsyncCallback(ContextReceivedCallback), null);

            Log("GwListener: Слушатель запущен.", Properties.Resources.listenerStarted);
            Console.WriteLine("Press C to terminate process...");
            Console.WriteLine("Press R to restart process...");

            while (true)
            {
                Thread.Sleep(1000);
                // По идее, мы сюда больше не вернемся, так что ждем...
                ConsoleKeyInfo c = Console.ReadKey(true);
                if (c.Key == ConsoleKey.C || c.Key == ConsoleKey.R)
                {
                    // Если нажаты C или Ctrl-C завершим работу слушателя
                    // Остановим слушатель
                    Stop();
                    Log("GWListener: Заврешение. {0} запросов в очереди {1} обрабатываются", Conveyor.Count, processes);
                    Console.WriteLine("GWListener: Заврешение. {0} запросов в очереди {1} обрабатываются", Conveyor.Count, processes);
                    // Пока выполняются фоновые процессы будем ждать завершения
                    WaitHandle.WaitAll(me);
                    if (c.Key == ConsoleKey.R)
                    {
                        Program.Reload = true;
                    }
                    else
                    {
                        Program.Reload = false;
                    }
                    break;
                    // throw new ApplicationException(Properties.Resources.cancelledByUser);
                }
            }

            // Закроем слушатель
            Dispose();
        }