GetRequestStream方法和挂起线程

时间:2014-08-19 10:54:51

标签: c# multithreading httprequest httpresponse

假设我有以下代码:

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()执行之前

。以下是我的活动主题的屏幕截图:

enter image description here

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

按下F10后,我们执行了http.GetRequestStream()方法。这是活动主题的更新截图:

enter image description here

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

我是否以某种方式滥用GetRequestStream

1 个答案:

答案 0 :(得分:0)

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

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

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

请注意,这些都是内部类,这些实现细节可能随时发生变化。