Execute a WebRequest in a Background thread while

2019-03-01 17:35发布

问题:

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

};

回答1:

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...



回答2:

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