Helpers - компьютеры, интернет, программирование

Async WebClient не совсем Async?

Я создал запрос асинхронного 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, не должен ли он быть асинхронным?

Редактировать:

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

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


  • Вы можете установить точку останова до / после UploadDataAsync, чтобы убедиться, что это действительно блокирующий вызов - однако, согласно MSDN, он не блокирует - возможно, вы должны блокировать где-то еще? 07.02.2011
  • Я протестировал его, и, к сожалению, это код, который блокирует вызывающий поток. 08.02.2011
  • Используйте Debug + Break All, пока он блокирует и копирует стек вызовов. Сделайте это пару раз, опубликуйте тот, который лучше всего повторяется. 08.02.2011
  • Я разместил свой стек вызовов выше. Это то, что вы хотели увидеть? Похоже, информации недостаточно! 08.02.2011

Ответы:


1

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

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

11.02.2011
  • @Brad Здесь дополнительная информация. 27.02.2013

  • 2

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

    07.02.2011
  • Боюсь, насколько я могу судить, в моем приложении не установлен атрибут STAThread. 08.02.2011

  • 3

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

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

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

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

    20.09.2013
  • UploadyDataAsync не возвращает Task и, следовательно, не ожидает. msdn.microsoft.com/en-us/library /ms144225(v=vs.110).aspx 22.02.2017
  • Новые материалы

    Интуитивное понимание тензоров в машинном обучении
    Тензор является важной концепцией во многих научных областях, таких как математика, физика, обработка сигналов и компьютерное зрение, и это лишь некоторые из них. В математике тензор — это..

    Использование машинного обучения для диагностики болезни Альцгеймера, часть 4
    Маркеры семантической согласованности для ранней диагностики болезни Альцгеймера (arXiv) Автор: Давиде Колла , Маттео Дельсанто , Марко Агосто , Бенедетто Витиелло , Даниэле Паоло Радичони..

    Почему объяснимость так важна прямо сейчас?
    По мере того, как системы искусственного интеллекта и инструменты на основе машинного обучения распространяются в нашей повседневной жизни, как практики, так и критики все чаще заявляют о..

    Анимированный математический анализ
    Использование Manim для создания математических анимированных визуализаций Визуализация данных помогает понять скрытые закономерности в данных, которые невозможно визуализировать..

    Создание простого слайдера изображений с помощью JavaScript
    Узнайте, как создать базовый слайдер изображений с помощью HTML, CSS и JavaScript. Введение В этом уроке мы создадим удобный слайдер изображений, используя JavaScript, HTML и CSS. Ползунок..

    Создание базы данных с помощью супергероя «Python»
    В этом посте мы узнаем, как создать «базу данных SQLite с помощью модуля python sqlite3, создав простую функцию входа и регистрации. Готовы ли вы к этому путешествию? Если да , давайте приступим..

    ИИ для чайников: руководство для начинающих по пониманию будущего технологий
    Вы чувствуете, что остались позади в мире ИИ? Не волнуйтесь, вы не одиноки! Со всей этой шумихой вокруг искусственного интеллекта может быть трудно понять, с чего начать. Но не позволяйте сленгу..