当UI线程被阻塞时在后台线程中执行WebRequest
问题描述:
为什么下面的代码在5秒后执行WebRequests时UI线程不再被阻塞? Thread.Sleep
位于UI线程中,而WebRequest的实例化和调用都发生在ThreadPool的线程内。当UI线程被阻塞时在后台线程中执行WebRequest
Loaded += (sender, args) => {
for (int i = 0; i < 5; i++) {
ThreadPool.QueueUserWorkItem(state => {
var request = WebRequest.CreateHttp("http://google.com");
request.BeginGetResponse(ar => Debug.WriteLine("Request finished"), null);
});
Thread.Sleep(1000);
}
};
我应该写什么代码才能在UI线程被阻塞时在后台线程中执行WebRequest?
编辑: ...更具体。为什么这个请求在10秒后被执行,因为它在后台线程中?
Loaded += (sender, args) => {
ThreadPool.QueueUserWorkItem(state => {
var request = WebRequest.CreateHttp("http://google.com");
request.BeginGetResponse(ar => Debug.WriteLine("Request finished"), null);
});
Thread.Sleep(10000);
};
答
我问几乎相同的问题在这里(我将立即关闭,我发现你的): DownloadStringAsync requires UI thread?
答案是,所有的网络代码最终是编组到第5版之前的Silverlight中的UI线程。不幸的是,即使我针对Silverlight 5构建时,我仍然遇到同样的问题,所以我仍在调查...
答
也许你的意思是要做到这一点,而不是:
Loaded += (sender, args) =>
{
ThreadPool.QueueUserWorkItem(dummy =>
{
for (int i = 0; i < 5; i++)
{
ThreadPool.QueueUserWorkItem(state =>
{
var request = WebRequest.CreateHttp("http://google.com");
request.BeginGetResponse(ar => Debug.WriteLine("Request finished"), null);
});
Thread.Sleep(1000);
}
});
};
这完全不阻止用户界面和调试的短信进入每一秒。或者你想要的行为是什么?你真的想阻止用户界面(你不应该......)?
编辑(你的编辑后):
我明白了。这是一种反直觉,我没有立即回答。我强烈怀疑这个请求需要一些UI线程活动。你的主线程应该始终是响应式的,永远不要阻塞,所以这不成问题。除非你阻止主线程。所以他们可能会为了这个有缺陷的情况而优化自己的工作(这是)。
不过,答案会很有趣。我从桌面世界知道,浏览器相关的东西需要主线程。因此,我建议不要阻止它了:)
谢谢您的回答。我知道你的解决方案有效,但这不是我正在寻找的。请看我编辑的问题。 – djsolid