5

I have created an Asynchronous WebClient request inside a class as follows:

public class Downstream
    {
        public bool StartDownstream()
        {
            WebClient client = new WebClient();

            client.Headers.Add("user-agent", "Mozilla/4.0 [...]");
            client.Headers.Add("Content-Type","application/x-www-form-urlencoded");
            try
            {

                byte[] postArray = Encoding.UTF8.GetBytes("somevar=foo&someothervar=bar");
                Uri uri = new Uri("http://www.examplesite.com/somepage.php");

                client.UploadDataCompleted += 
                new UploadDataCompletedEventHandler(client_UploadDataCompleted);
                client.UploadDataAsync(uri, postArray);
            }
            catch (WebException e)
            {
                MessageBox.Show("A regular Web Exception");
            }
            catch (NotSupportedException ne)
            {
                MessageBox.Show("A super Web Exception");
            }
            return true;
        }

        void client_UploadDataCompleted(object sender, UploadDataCompletedEventArgs e)
        {
            MessageBox.Show("The WebClient request completed");
        }
    }

I then create a new instance of the class and run the method here:

Downstream Downstream1 = new Downstream();
Downstream1.StartDownstream();

When I do so, the thread that the form is running on seems to hang until the WebClient gets a response back. Why is this? I have used the UploadDataAsync method so should it not be Asynchronous?

Edit:

This is my call stack:

    [External Code] 
>   Arcturus.exe!Arcturus.Downstream.StartDownstream() Line 36 + 0x18 bytes C#
    Arcturus.exe!Arcturus.MainWindow.btnLogin_Click(object sender, System.Windows.RoutedEventArgs e) Line 111 + 0x12 bytes  C#
    [External Code]

This is all that happens when I run my application, just hanging on the StartDownstream() and client.UploadDataAsync(uri, postArray); methods.

svick
  • 236,525
  • 50
  • 385
  • 514
Joel Kennedy
  • 1,581
  • 5
  • 19
  • 41
  • You could set a breakpoint before/after UploadDataAsync to check for yourself it is actually the blocking call - however, according to MSDN, that doesn't block - you must be blocking elsewhere perhaps? – Mike Atlas Feb 07 '11 at 20:58
  • I have tested it and unfortunately this is the code that is blocking the calling thread. – Joel Kennedy Feb 07 '11 at 21:17
  • 2
    Use Debug + Break All while it blocks and copy the call stack. Do this a couple of times, post the one that repeats best. – Hans Passant Feb 07 '11 at 21:31
  • I have posted my call stack above. Is that what you wanted to see? It doesn't seem like enough information! – Joel Kennedy Feb 07 '11 at 21:57

3 Answers3

4

My problem I had was to do with the WebClient using the same thread as the UI, regardless of it being Async or not. I decided to use a BackgroundWorker instead.

Thanks for the answers!

Joel Kennedy
  • 1,581
  • 5
  • 19
  • 41
0

Just a guess, does your main form have the STAThread attribute set on it? If you application doesn't have any COM calls then you can safely remove this attribute. Perhaps it may force UploadDataAsync to run in the same thread as the main form, thus blocking it.

Community
  • 1
  • 1
Mike Atlas
  • 8,193
  • 4
  • 46
  • 62
-2

First, you need to use await keyword before client.UploadDataAsync(uri, postArray). Therefore it should be " await client.UploadDataAsync(uri, postArray); "

Second, since you use await keyword in your method, you need to write async beginning of your method declaration and Task instead of bool. Therefore it should be async public Task StartDownstream(){..}

After these two steps, since your StardDownstream method async you also should await it. Use it like await Downstream1.StartDownstream();

If I have any mistake, let me know because I am new to this topic.

  • 1
    UploadyDataAsync doesn't return a Task and therefore isn't awaitable. https://msdn.microsoft.com/en-us/library/ms144225(v=vs.110).aspx – Tim Feb 22 '17 at 17:57