/// <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); } }
/// <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(); }