多线程与.net的HttpListener [英] Multi-threading with .Net HttpListener

查看:938
本文介绍了多线程与.net的HttpListener的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个监听器:

 监听器=新的HttpListener();
。监听器prefixes.Add(@的http:// +:8077 /);
listener.Start();
listenerThread =新主题(HandleRequests);
listenerThread.Start();
 

和我在处理请求:

 私人无效HandleRequests()
{
    而(listener.IsListening)
    {
        VAR上下文= listener.BeginGetContext(新的AsyncCallback(ListenerCallback),监听器);
        context.AsyncWaitHandle.WaitOne();
    }
}

私人无效ListenerCallback(IAsyncResult的AR)
{
    VAR监听= ar.AsyncState为的HttpListener;

    VAR上下文= listener.EndGetContext(AR);

    //做一些东西
}
 

我想编写无效停止()以这样的方式,即:

  1. 这将阻塞,直到所有当前处理的请求将结束(即会等待所有线程,以做一些东西)。
  2. 虽然它会等待已经开始的请求,它不会允许任何更多的请求(即在返回 ListenerCallback 的开始)。
  3. 之后,它会调用 listener.Stop() listener.IsListening 成了假)。

这怎么可能写呢?

修改:你怎么看待这个解决方案怎么样?是否安全?

 公共无效停止()
{
    锁(本)
    {
        isStopping = TRUE;
    }
    resetEvent.WaitOne(); //初始设置为true
    listener.Stop();
}

私人无效ListenerCallback(IAsyncResult的AR)
{
    锁(本)
    {
        如果(isStopping)
            返回;

        resetEvent.Reset();
        numberOfRequests ++;
    }

    VAR监听= ar.AsyncState为的HttpListener;

    VAR上下文= listener.EndGetContext(AR);

    //做一些东西

    锁(本)
    {
        如果(--numberOfRequests == 0)
            resetEvent.Set();
    }
}
 

解决方案

我咨询了我的code在我的问题编辑的一部分,我已经决定接受它的一些修改:

 公共无效停止()
{
    锁(更衣室)
    {
        isStopping = TRUE;
    }
    resetEvent.WaitOne(); //初始设置为true
    listener.Stop();
}

私人无效ListenerCallback(IAsyncResult的AR)
{
    锁定(柜)//锁定在,这是一个坏主意,但我忘了这件事之前,
    {
        如果(isStopping)
            返回;

        resetEvent.Reset();
        numberOfRequests ++;
    }

    尝试
    {
        VAR监听= ar.AsyncState为的HttpListener;

        VAR上下文= listener.EndGetContext(AR);

        //做一些东西
    }
    终于//确保波纹管code将被执行
    {
        锁(更衣室)
        {
            如果(--numberOfRequests == 0)
                resetEvent.Set();
        }
    }
}
 

I have a listener:

listener = new HttpListener();
listener.Prefixes.Add(@"http://+:8077/");
listener.Start();
listenerThread = new Thread(HandleRequests);
listenerThread.Start();

And I am handling requests:

private void HandleRequests()
{
    while (listener.IsListening)
    {
        var context = listener.BeginGetContext(new AsyncCallback(ListenerCallback), listener);
        context.AsyncWaitHandle.WaitOne();
    }
}

private void ListenerCallback(IAsyncResult ar)
{
    var listener = ar.AsyncState as HttpListener;

    var context = listener.EndGetContext(ar);

    //do some stuff
}

I would like to write void Stop() in such a way, that:

  1. It will block until all currently handled requests will end (ie. will wait for all threads to "do some stuff").
  2. While it will wait for already started requests, it will not allow any more requests (ie. return at the beginning of ListenerCallback).
  3. After that it will call listener.Stop() (listener.IsListening became false).

How could it be write?

EDIT: What do you think about this solution? Is it safe?

public void Stop() 
{
    lock (this)
    {
        isStopping = true;
    }
    resetEvent.WaitOne(); //initially set to true
    listener.Stop();
}

private void ListenerCallback(IAsyncResult ar)
{
    lock (this)
    {
        if (isStopping)
            return;

        resetEvent.Reset();
        numberOfRequests++;
    }

    var listener = ar.AsyncState as HttpListener;

    var context = listener.EndGetContext(ar);

    //do some stuff

    lock (this)
    {
        if (--numberOfRequests == 0)
            resetEvent.Set();
    }
}

解决方案

I have consulted my code in EDIT part of my question and I've decided to accept it with some modifications:

public void Stop() 
{
    lock (locker)
    {
        isStopping = true;
    }
    resetEvent.WaitOne(); //initially set to true
    listener.Stop();
}

private void ListenerCallback(IAsyncResult ar)
{
    lock (locker) //locking on this is a bad idea, but I forget about it before
    {
        if (isStopping)
            return;

        resetEvent.Reset();
        numberOfRequests++;
    }

    try
    {
        var listener = ar.AsyncState as HttpListener;

        var context = listener.EndGetContext(ar);

        //do some stuff
    }
    finally //to make sure that bellow code will be executed
    {
        lock (locker)
        {
            if (--numberOfRequests == 0)
                resetEvent.Set();
        }
    }
}

这篇关于多线程与.net的HttpListener的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆