【问题标题】:GetRequestStream method and hanging threadGetRequestStream 方法和挂起线程
【发布时间】:2014-08-19 10:54:50
【问题描述】:

假设我有以下代码:

private string PostData(string functionName, string parsedContent)
    {
        string url = // some url;
        
        var http = (HttpWebRequest)WebRequest.Create(new Uri(url));

        http.Accept = "application/json";
        http.ContentType = "application/json";
        http.Method = "POST";
        http.Timeout = 15000; // 15 seconds

        Byte[] bytes = Encoding.UTF8.GetBytes(parsedContent);

        using (Stream newStream = http.GetRequestStream())
        {
            newStream.Write(bytes, 0, bytes.Length);
        }

        using (WebResponse response = http.GetResponse())
        {
            using (var stream = response.GetResponseStream())
            {
                var sr = new StreamReader(stream);
                var content = sr.ReadToEnd();
                return content;
            }
        }
    }

我在这行代码上设置了一个断点:

using (Stream newStream = http.GetRequestStream())

http.GetRequestStream() 被执行之前。这是我的活动线程的屏幕截图:

如您所见,整个方法在ThreadId = 3 的后台线程中运行。

按下 F10 后,我们会执行 http.GetRequestStream() 方法。这是活动线程的更新屏幕截图:

如您所见,现在我们有一个额外的活动线程处于等待状态。可能是http.GetRequestStream() 方法产生了它。一切都很好,但是.. 这个线程在整个应用生命周期中一直挂起,这似乎不是预期的行为。

我是否以某种方式滥用了GetRequestStream

【问题讨论】:

  • 是的,我还读到 GetRequestStream 异步工作,这解释了额外的线程,但它没有解释为什么这个线程在关闭和处理流后继续存在。对我来说,这个线程似乎是某种僵局或类似的东西。
  • @rene,您能否发表您的评论作为答案,以便我接受?我认为这是对这个问题的充分解释。

标签: c# multithreading httprequest httpresponse


【解决方案1】:

如果我使用ilspy,看起来请求是异步发送的。这将解释额外的线程。

再深入一点,HttpWebRequest 创建了一个静态TimerQueue,其中包含一个线程和一个永无止境的循环,其中包含一个Monitor.WaitAny。 appdomain 中的每个 webrequest 都会为超时处理注册一个计时器回调,并且所有这些回调都由该线程处理。由于它是静态的,该实例永远不会被垃圾收集,因此它将保持线程。

它确实注册了AppDomain.Unload 事件,所以如果触发它会清理它的资源,包括任何线程。

请注意,这些都是内部类,这些实现细节可能随时更改。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-15
    • 1970-01-01
    • 1970-01-01
    • 2012-04-18
    • 2014-09-15
    • 1970-01-01
    相关资源
    最近更新 更多