Nano Hash - криптовалюты, майнинг, программирование

Остановить и перезапустить HttpListener?

Я работаю над приложением, которое имеет HttpListener. Моя цель состоит в том, чтобы пользователь мог включать и выключать прослушиватель по своему выбору. Я поместил Listener в новый поток, и у меня возникла проблема с прерыванием этого потока. Я где-то читал, что если вы попытаетесь прервать поток, который находится в неуправляемом контексте, то, как только он снова войдет в управляемый контекст, ThreadAbortException будет запущен. Похоже, что метод GetContext() HttpListener неуправляем, потому что, когда я пытаюсь прервать поток, ничего не происходит, пока я не сделаю веб-запрос к моему приложению. ТОГДА поток выходит. Проблема в том, что когда я пытаюсь убить поток, я могу снова запустить поток позже на том же порту, и HttpListenerException уходит, говоря, что префикс уже зарегистрирован.

Как я могу убить перекрестный поток HttpListener? Есть ли управляемая альтернатива GetContext(), которая позволит прервать поток? Могу ли я прервать поток таким образом, чтобы неуправляемый код остановился?


  • Если возможно, реализуйте свой HttpListener, используя BeginGetContext() и EndGetContext(). 05.06.2013
  • Не могли бы вы опубликовать код, который показывает, как вы начинаете поток и т. Д.? - Вероятно, вы можете прокрасться где-нибудь CancellationToken, и всякий раз, когда пользователь выключает прослушиватель, вы можете вызывать метод Cancel для CancellationToken, у которого есть продолжение, которое говорит, что он должен вызывать HttpListener.Stop(). 05.06.2013

Ответы:


1

Как насчет чего-то вроде:

public class XListener
{
    HttpListener listener;

    public XListener(string prefix)
    {
        listener = new HttpListener();
        listener.Prefixes.Add(prefix);
    }

    public void StartListen()
    {
        if (!listener.IsListening)
        {
            listener.Start();

            Task.Factory.StartNew(async () =>
            {
                while (true) await Listen(listener);
            }, TaskCreationOptions.LongRunning);

            Console.WriteLine("Listener started");
        }
    }

    public void StopListen()
    {
        if (listener.IsListening)
        {
            listener.Stop();
            Console.WriteLine("Listener stopped");
        }
    }

    private async Task Listen(HttpListener l)
    {
        try
        {
            var ctx = await l.GetContextAsync();

            var text = "Hello World";
            var buffer = Encoding.UTF8.GetBytes(text);

            using (var response = ctx.Response)
            {
                ctx.Response.ContentLength64 = buffer.Length;
                ctx.Response.OutputStream.Write(buffer, 0, buffer.Length);
            }
        }
        catch (HttpListenerException)
        {
            Console.WriteLine("screw you guys, I'm going home!");
        }
    }
}

Применение:

var x = new XListener("http://locahost:8080");

x.StartListen();
Thread.Sleep(500); // test purpose only

x.StopListen();
Thread.Sleep(500); // test purpose only

x.StartListen();

/* OUTPUT:
=> Listener started
=> Listener stopped
=> screw you guys, I'm going home!
=> Listener started */
05.06.2013

2

Вам нужно сигнализировать потоку о вызове HttpListener.Stop() и дождаться завершения потока, вызвав Thread.Join().

05.06.2013
  • с помощью глобальной переменной. Я предполагаю, что ваш прослушивающий поток проверяет входящие соединения, поэтому вы можете сделать что-то вроде: while(!shutdown){ //listen }; слушатель.Стоп(); и в потоке сигнализации вы должны сделать: shutdown=true; listenThread.Join(); 05.06.2013
  • matt-dot-net: Проблема в том, что поток ожидает HttpListener.GetContextAsync() и поэтому не может регулярно проверять, запрошен ли Stop. Увы нет перегрузки GetContextAsync(CancellationToken). Единственный способ заставить поток прекратить прослушивание — это вызвать HttpListener.Stop() 17.04.2019
  • GetContextAsync() не блокируется, если вы не используете await. Вам необходимо обеспечить (а)синхронность получения и обработки входящих подключений. Этому циклу должно быть разрешено проверять завершение работы, а затем очищать сгенерированные асинхронные задачи. Задача, возвращаемая из GetContextAsync(), — это то, с чего вам нужно начать, или, возможно, использовать исходный шаблон IAsyncResult Begin/End GetContext. 12.06.2019

  • 3

    Все, что вам нужно сделать, это остановить слушателя. Поскольку ваш поток прослушивателя заблокирован в GetContext, вам нужно будет сделать это в другом потоке. IIRC это приведет к выбросу GetContext, поэтому вам нужно будет обработать это исключение и очистить его. Вызов Thread.Abort должен быть вашим последним средством и не приведет к тому, что слушатель перестанет слушать, пока он все равно не будет собран мусором.

    05.06.2013

    4
  • Вы должны объяснить, как это работает и что именно делает. Это улучшит этот ответ 03.11.2020
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..