2011-12-11 67 views
1

为什么下面的代码在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); 

}; 

回答

1

我问几乎相同的问题在这里(我将立即关闭,我发现你的): DownloadStringAsync requires UI thread?

答案是,所有的网络代码最终是编组到第5版之前的Silverlight中的UI线程。不幸的是,即使我针对Silverlight 5构建时,我仍然遇到同样的问题,所以我仍在调查...

0

也许你的意思是要做到这一点,而不是:

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线程活动。你的主线程应该始终是响应式的,永远不要阻塞,所以这不成问题。除非你阻止主线程。所以他们可能会为了这个有缺陷的情况而优化自己的工作(这是)。

不过,答案会很有趣。我从桌面世界知道,浏览器相关的东西需要主线程。因此,我建议不要阻止它了:)

+0

谢谢您的回答。我知道你的解决方案有效,但这不是我正在寻找的。请看我编辑的问题。 – djsolid

相关问题