Async WebClient не является действительно Async? - PullRequest
5 голосов
/ 07 февраля 2011

Я создал асинхронный запрос WebClient внутри класса следующим образом:

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

Затем я создаю новый экземпляр класса и запускаю метод здесь:

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

Когда я это делаю, поток, в котором работает форма, кажется, зависает, пока WebClient не получит ответ. Почему это? Я использовал метод UploadDataAsync, поэтому он не должен быть асинхронным?

Edit:

Это мой стек вызовов:

    [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]

Это все, что происходит, когда я запускаю свое приложение, просто зависая на методах StartDownstream() и client.UploadDataAsync(uri, postArray);.

Ответы [ 3 ]

3 голосов
/ 11 февраля 2011

Моя проблема заключалась в том, что WebClient использовал тот же поток, что и пользовательский интерфейс, независимо от того, был он асинхронным или нет. Я решил использовать BackgroundWorker вместо этого.

Спасибо за ответы!

0 голосов
/ 21 сентября 2013

Во-первых, вам нужно использовать ключевое слово await перед client.UploadDataAsync (uri, postArray). Следовательно, это должно быть "ожидание клиента.UploadDataAsync (uri, postArray);"

Во-вторых, поскольку вы используете ключевое слово await в своем методе, вам нужно написать асинхронное начало объявления метода и Task вместо bool. Поэтому это должна быть асинхронная публичная задача StartDownstream () {..}

После этих двух шагов, поскольку ваш метод StardDownstream асинхронный, вы также должны его дождаться. Используйте его как await Downstream1.StartDownstream ();

Если у меня возникнут ошибки, дайте мне знать, потому что я новичок в этой теме.

0 голосов
/ 08 февраля 2011

Скорее всего, в вашей главной форме установлен атрибут STAThread ? Если в вашем приложении нет вызовов COM, вы можете безопасно удалить этот атрибут . Возможно, это может заставить UploadDataAsync работать в том же потоке, что и основная форма, блокируя его.

...