page contents

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

本文讲述了c# – 针对HttpListener的多线程应答!具有很好的参考价值,希望对大家有所帮助。一起跟随六星小编过来看看吧,具体如下:

attachments-2022-05-iQCuPVdY627f0fe56fad3.png

本文讲述了c# – 针对HttpListener的多线程应答!具有很好的参考价值,希望对大家有所帮助。一起跟随六星小编过来看看吧,具体如下:

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

我有单线程进程,执行了很长时间.我需要几个用户才能访问执行此过程,我选择http协议来管理调用.

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

这是实施:

  1. usingSystem;
  2. usingSystem.Net;
  3. usingSystem.Reflection;
  4. usingSystem.Runtime.InteropServices;
  5. usingSystem.Threading;
  6. usingSystem.Threading.Tasks;
  7.  
  8. namespace simplehttp
  9. {
  10. classProgram
  11. {
  12. privatestaticSystem.AsyncCallback task;
  13. privatestaticSystem.Threading.ManualResetEvent mre =newSystem.Threading.ManualResetEvent(false);// Notifies one or more waiting threads that an event has occurred.
  14. privatestaticHttpListenerContext workingContext =null;
  15.  
  16. publicstaticbool isBackgroundWorking()
  17. {
  18. return mre.WaitOne(0);
  19. }
  20. staticvoidMain(string[] args)
  21. {
  22. newThread(()=>
  23. {
  24. Thread.CurrentThread.IsBackground=true;
  25. while(true)
  26. {
  27. Console.WriteLine(" waitOne "+ isBackgroundWorking());
  28. mre.WaitOne();// Blocks the current thread until the current WaitHandle receives a signal.
  29. Console.WriteLine(" do job"+" ["+Thread.CurrentThread.Name+":"+Thread.CurrentThread.ManagedThreadId+" ]\n");
  30. HttpListenerRequest request = workingContext.Request;
  31. HttpListenerResponse response = workingContext.Response;
  32. string responseString ="WORK "+DateTime.Now;
  33. byte[] buffer =System.Text.Encoding.UTF8.GetBytes(responseString);
  34. response.ContentLength64= buffer.Length;
  35. System.IO.Stream output = response.OutputStream;
  36. Thread.Sleep(10000);
  37. output.Write(buffer,buffer.Length);
  38. output.Close();
  39. Console.WriteLine(" "+ responseString +"\t"+DateTime.Now);
  40. workingContext =null;
  41. mre.Reset();// Sets the state of the event to nonsignaled,causing threads to block.
  42. }
  43. }).Start();
  44.  
  45. // Create a listener.
  46. HttpListener listener =newHttpListener();
  47.  
  48. listener.Prefixes.Add("http://localhost:6789/index/");
  49. listener.Start();
  50. Console.WriteLine("Listening..."+" ["+Thread.CurrentThread.Name+":"+Thread.CurrentThread.ManagedThreadId+" ]\n");
  51.  
  52. task =newAsyncCallback(ListenerCallback);
  53.  
  54. IAsyncResult resultM = listener.BeginGetContext(task,listener);
  55. Console.WriteLine("Waiting for request to be processed asyncronously.");
  56.  
  57. Console.ReadKey();
  58. Console.WriteLine("Request processed asyncronously.");
  59. listener.Close();
  60. }
  61.  
  62. privatestaticvoidListenerCallback(IAsyncResult result)
  63. {
  64. HttpListener listener =(HttpListener) result.AsyncState;
  65.  
  66. //If not listening return immediately as this method is called one last time after Close()
  67. if(!listener.IsListening)
  68. return;
  69.  
  70. HttpListenerContext context = listener.EndGetContext(result);
  71. listener.BeginGetContext(task,listener);
  72.  
  73. if(workingContext ==null&&!isBackgroundWorking())
  74. {
  75. // Background work
  76. workingContext = context;
  77. mre.Set();//Sets the state of the event to signaled,allowing one or more waiting threads to proceed.
  78. }
  79. else
  80. {
  81. HttpListenerRequest request = context.Request;
  82. HttpListenerResponse response = context.Response;
  83. string responseString ="BUSY "+DateTime.Now+" ["+Thread.CurrentThread.Name+":"+Thread.CurrentThread.ManagedThreadId;
  84. byte[] buffer =System.Text.Encoding.UTF8.GetBytes(responseString);
  85. response.ContentLength64= buffer.Length;
  86. System.IO.Stream output = response.OutputStream;
  87. output.Write(buffer,buffer.Length);
  88. output.Close();
  89. Console.WriteLine(responseString +"\t"+DateTime.Now);
  90. }
  91. }
  92. }
  93. }

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

  1. waitOne False
  2. Listening...[:10]
  3.  
  4. Waitingfor request to be processed asyncronously.
  5. do job [:11]
  6.  
  7. WORK 1/24/201610:34:01 AM 1/24/201610:34:11 AM
  8. waitOne False
  9. do job [:11]
  10.  
  11. WORK 1/24/201610:34:11 AM 1/24/201610:34:21 AM
  12. waitOne False

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

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

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

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

  1. HttpListenerContext context = listener.EndGetContext(result);
  2. listener.BeginGetContext(task,listener);

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

  1. privatestaticvoidListenerCallback(IAsyncResult result)
  2. {
  3. HttpListener listener =(HttpListener) result.AsyncState;
  4.  
  5. //If not listening return immediately as this method is called one last time after Close()
  6. if(!listener.IsListening)
  7. return;
  8.  
  9. HttpListenerContext context = listener.EndGetContext(result);
  10.  
  11. while(true)
  12. {
  13. if(workingContext ==null&&!isBackgroundWorking())
  14. {
  15. // Background work
  16. workingContext = context;
  17. mre.Set();//Sets the state of the event to signaled,allowing one or more waiting threads to proceed.
  18. }
  19. else
  20. {
  21. HttpListenerRequest request = context.Request;
  22. HttpListenerResponse response = context.Response;
  23. string responseString ="BUSY "+DateTime.Now+" ["+Thread.CurrentThread.Name+":"+
  24. Thread.CurrentThread.ManagedThreadId;
  25. byte[] buffer =System.Text.Encoding.UTF8.GetBytes(responseString);
  26. response.ContentLength64= buffer.Length;
  27. System.IO.Stream output = response.OutputStream;
  28. output.Write(buffer,buffer.Length);
  29. output.Close();
  30. Console.WriteLine(responseString +"\t"+DateTime.Now);
  31. }
  32. context=listener.GetContext();
  33. }
  34. }

解决方法

发布的代码与它应该完全一样:

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

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

更多相关技术内容咨询欢迎前往并持续关注六星社区了解详情。

如果你想用Python开辟副业赚钱,但不熟悉爬虫与反爬虫技术,没有接单途径,也缺乏兼职经验
关注下方微信公众号:Python编程学习圈,获取价值999元全套Python入门到进阶的学习资料以及教程,还有Python技术交流群一起交流学习哦。

attachments-2022-06-e22wZ5Ux62b410f1275d7.jpeg

  • 发表于 2022-05-14 10:12
  • 阅读 ( 419 )
  • 分类:C/C++开发

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
轩辕小不懂
轩辕小不懂

2403 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1312 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章