c# – 针对HttpListener的多线程应答

c# – 针对HttpListener的多线程应答,第1张

概述我有单线程进程,执行了很长时间.我需要几个用户才能访问执行此过程,我选择http协议来管理调用. 当然,当一个过程正在运行时,其他人应该等到它完成.如果进程可用,则执行.如果没有,则发送BUSY应答. 这是实施: using System;using System.Net;using System.Reflection;using System.Runtime.InteropServices 我有单线程进程,执行了很长时间.我需要几个用户才能访问执行此过程,我选择http协议来管理调用.

当然,当一个过程正在运行时,其他人应该等到它完成.如果进程可用,则执行.如果没有,则发送BUSY应答.

这是实施:

using System;using System.Net;using System.Reflection;using System.Runtime.InteropServices;using System.Threading;using System.Threading.Tasks;namespace simplehttp{    class Program    {        private static System.AsyncCallback task;        private static System.Threading.ManualresetEvent mre = new System.Threading.ManualresetEvent(false);// NotifIEs one or more waiting threads that an event has occurred.         private static httpListenerContext workingContext = null;        public static bool isBackgrounDWorking()        {            return mre.WaitOne(0);        }        static voID Main(string[] args)        {            new Thread(() =>            {                Thread.CurrentThread.IsBackground = true;                while (true)                {                    Console.Writeline("    waitOne " + isBackgrounDWorking());                    mre.WaitOne(); // Blocks the current thread until the current WaitHandle receives a signal.                    Console.Writeline("    do job" + " [" + Thread.CurrentThread.name + ":" + Thread.CurrentThread.ManagedThreadID + " ]\n");                    httpListenerRequest request = workingContext.Request;                    httpListenerResponse response = workingContext.Response;                    string responseString = "WORK " + DateTime.Now ;                    byte[] buffer = System.Text.EnCoding.UTF8.GetBytes(responseString);                    response.ContentLength64 = buffer.Length;                    System.IO.Stream output = response.OutputStream;                    Thread.Sleep(10000);                    output.Write(buffer,buffer.Length);                    output.Close();                    Console.Writeline("    " + responseString + "\t" + DateTime.Now);                    workingContext = null;                    mre.reset(); // Sets the state of the event to nonsignaled,causing threads to block.                }            }).Start();            // Create a Listener.            httpListener Listener = new httpListener();            Listener.Prefixes.Add("http://localhost:6789/index/");            Listener.Start();            Console.Writeline("Listening..." + " [" + Thread.CurrentThread.name + ":" + Thread.CurrentThread.ManagedThreadID + " ]\n");            task = new AsyncCallback(ListenerCallback);            IAsyncResult resultM = Listener.BeginGetContext(task,Listener);            Console.Writeline("Waiting for request to be processed asyncronously.");            Console.ReadKey();            Console.Writeline("Request processed asyncronously.");            Listener.Close();        }        private static voID ListenerCallback(IAsyncResult result)        {            httpListener Listener = (httpListener) result.AsyncState;            //If not Listening return immediately as this method is called one last time after Close()            if (!Listener.IsListening)                return;            httpListenerContext context = Listener.EndGetContext(result);            Listener.BeginGetContext(task,Listener);            if (workingContext == null && !isBackgrounDWorking())            {                // Background work                workingContext = context;                mre.Set(); //Sets the state of the event to signaled,allowing one or more waiting threads to proceed.            }            else            {            httpListenerRequest request = context.Request;            httpListenerResponse response = context.Response;            string responseString = "BUSY "+ DateTime.Now + " [" + Thread.CurrentThread.name + ":" + Thread.CurrentThread.ManagedThreadID;            byte[] buffer = System.Text.EnCoding.UTF8.GetBytes(responseString);            response.ContentLength64 = buffer.Length;            System.IO.Stream output = response.OutputStream;            output.Write(buffer,buffer.Length);            output.Close();            Console.Writeline(responseString + "\t" + DateTime.Now);            }        }    }}

为了测试我做2个http调用.我希望有2个不同的答案WORK和BUSY.
但是我看到第二个请求先等待完成然后执行.

waitOne FalseListening... [:10 ]Waiting for request to be processed asyncronously.      do job [:11 ]      WORK 1/24/2016 10:34:01 AM  1/24/2016 10:34:11 AM      waitOne False      do job [:11 ]      WORK 1/24/2016 10:34:11 AM  1/24/2016 10:34:21 AM      waitOne False

我理解它应该如何运作有什么问题?

更新(太多评论没有被SO鼓励):
我的代码看起来很尴尬,因为它是真实进程的复制.在“我的”应用程序中,工作过程是主要过程,在某些特定时刻运行嵌入式C#代码具有“礼貌”.因此,我无法运行新任务来处理请求,并且它必须是异步的,因为工作流程完成自己的工作,并且只调用从属代码片段以在数据可用时通知客户端.它是异步的,因为代码被调用并且应该尽快完成,否则它将阻止主应用程序.
我将尝试添加其他线程与同步调用,并看到它影响情况.

此示例中未使用调试器来干扰打印到控制台的实时进程和时间戳.调试很棒且必要但在这种情况下我尝试用输出替换以避免同步/等待场景中的额外actor.

应用程序本身并不是繁重的对话. 1-3个客户很少向主要申请人询问答案. http协议用于方便而不是繁重或经常对话.看起来像IE这样的浏览器工作正常(windows到windows会话?),有些像Chrome(更多系统不可知)复制我的应用程序行为.看看时间戳,Chrome,IE,Chrome和最后一个Chrome仍然进入了WORK流程.顺便说一句,每个会话建议更改代码,现在在检索前一个请求后立即发出新请求.

httpListenerContext context = Listener.EndGetContext(result);    Listener.BeginGetContext(task,Listener);

另外,根据建议,我改变了对syncroniuos的异步调用,结果仍然相同

private static voID ListenerCallback(IAsyncResult result){    httpListener Listener = (httpListener) result.AsyncState;    //If not Listening return immediately as this method is called one last time after Close()    if (!Listener.IsListening)        return;    httpListenerContext context = Listener.EndGetContext(result);    while (true)    {        if (workingContext == null && !isBackgrounDWorking())        {            // Background work            workingContext = context;            mre.Set(); //Sets the state of the event to signaled,allowing one or more waiting threads to proceed.        }        else        {            httpListenerRequest request = context.Request;            httpListenerResponse response = context.Response;            string responseString = "BUSY " + DateTime.Now + " [" + Thread.CurrentThread.name + ":" +                                    Thread.CurrentThread.ManagedThreadID;            byte[] buffer = System.Text.EnCoding.UTF8.GetBytes(responseString);            response.ContentLength64 = buffer.Length;            System.IO.Stream output = response.OutputStream;            output.Write(buffer,buffer.Length);            output.Close();            Console.Writeline(responseString + "\t" + DateTime.Now);        }        context=Listener.GetContext();    }}
解决方法 发布的代码与它应该完全一样:

无法重现.我想这回答了这个问题,因为显然你错误地推动了测试工作量.我通过反复点击fiddler composer发送按钮开车.

谢谢你发布可执行代码.我应该早点尝试过!

总结

以上是内存溢出为你收集整理的c# – 针对HttpListener的多线程应答全部内容,希望文章能够帮你解决c# – 针对HttpListener的多线程应答所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1249090.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-07
下一篇 2022-06-07

发表评论

登录后才能评论

评论列表(0条)

保存