假设我有以下代码:
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
?
答案 0 :(得分:0)
如果我使用ilspy,则看起来请求是异步发送的。这可以解释额外的线程。
稍微深一点HttpWebRequest
创建一个静态TimerQueue
,其中包含一个线程和一个永不停止的循环,其中包含Monitor.WaitAny
。 appdomain中的每个webrequest都会为超时处理注册一个计时器回调,所有这些回调都由该线程处理。由于它是静态的,实例永远不会被垃圾收集,因此它将保持线程的持有。
它注册了AppDomain.Unload
事件,所以如果触发它会清理它的资源,包括任何线程。
请注意,这些都是内部类,这些实现细节可能随时发生变化。