当 UI 线程被阻塞时,在后台线程中执行 WebRequest

发布于 2024-12-20 19:27:23 字数 891 浏览 0 评论 0原文

当 UI 线程不再被阻塞时,为什么下面的代码会在 5 秒后执行 WebRequests? Thread.Sleep 位于 UI 线程中,而 WebRequest 的实例化和调用都发生在 ThreadPool 的线程内。

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);

};

Why does the following code executes WebRequests after 5 secs when the UI Thread isn't being blocked anymore? Thread.Sleep is in the UI Thread while both Instantiation and Invocation of WebRequests occurring inside a Thread from ThreadPool.

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);
    }

};

What code should I write in order to execute a WebRequest in a background thread while the UI Thread is blocked?

EDIT:
...to be more specific. Why is this request being executed after 10 seconds since is in a background thread?

Loaded += (sender, args) => {

    ThreadPool.QueueUserWorkItem(state => {
        var request = WebRequest.CreateHttp("http://google.com");
        request.BeginGetResponse(ar => Debug.WriteLine("Request finished"), null);
    });
    Thread.Sleep(10000);

};

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦忆晨望 2024-12-27 19:27:23

我在这里问了几乎完全相同的问题(现在我找到了你的问题,我将结束这个问题):
DownloadStringAsync 需要 UI 线程?

答案是所有网络代码都是最终在版本 5 之前的 Silverlight 中编组到 UI 线程。不幸的是,即使我针对 Silverlight 5 进行构建,我仍然得到相同的结果问题,所以我还在调查...

I asked almost the exact same question here (which I'll close now that I found yours):
DownloadStringAsync requires UI thread?

The answer is that ALL network code is ultimately marshaled to the UI thread in Silverlight before version 5. Unfortunately, even when I build against Silverlight 5, I'm still getting the same issue, so I'm still investigating...

千鲤 2024-12-27 19:27:23

也许您打算这样做:

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,并且每秒都会出现调试消息。或者你想要的行为是什么?您真的想阻止 UI(您不应该...)?

编辑(编辑后):

我明白了。这有点违反直觉,我现在还没有答案。我强烈怀疑该请求需要一些 UI 线程活动。你的主线程应该始终响应并且永远不会阻塞,所以这不会有问题。除非你阻塞了主线程。因此,他们可能省去了针对有缺陷的情况进行优化的工作(就是这样)。

尽管如此,答案还是很有趣的。我从桌面世界知道浏览器相关的东西需要主线程。所以我建议不要再阻止它了:)

Maybe you mean to do this instead:

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);
        }
    });

};

This doesn't block the UI at all and the Debug message is coming every second. Or what would be your desired behavior? Do you really want to block the UI (you shouldn't...)?

EDIT (after your edit):

I see. That's kind of counter-intuitive and I don't have an answer right away. I strongly suspect the request requires some UI thread activity. Your main thread should always be responsive and never block so this would be no problem. Unless you block the main thread. So they might have spared themselves the work to optimize for the flawed case (which this is).

Nevertheless the answer would be interesting. I know from the desktop world that browser related stuff needs the main thread. So I recommend not blocking it anymore :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文