【问题标题】:Async WebClient not truly Async?Async WebClient 不是真正的异步?
【发布时间】:2015-04-10 22:24:28
【问题描述】:

我在一个类中创建了一个异步 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,这不会阻塞 - 你可能必须在其他地方阻塞?
  • 我已经测试过了,不幸的是这是阻塞调用线程的代码。
  • 在阻塞时使用 Debug + Break All 并复制调用堆栈。这样做几次,发布重复最好的那个。
  • 我已经在上面发布了我的调用堆栈。那是你想看到的吗?信息似乎不够!

标签: c# multithreading asynchronous webclient


【解决方案1】:

我遇到的问题是使用与 UI 相同的线程来处理 WebClient,无论它是否是异步的。我决定改用 BackgroundWorker。

感谢您的回答!

【讨论】:

  • @Brad Here's 更多信息。
【解决方案2】:

只是猜测,您的主窗体是否设置了STAThread 属性?如果您的应用程序没有任何 COM 调用,那么您可以safely remove this attribute。也许它可能会强制UploadDataAsync 与主窗体在同一线程中运行,从而阻塞它。

【讨论】:

  • 恐怕我的应用程序没有设置 STAThread 属性。
【解决方案3】:

首先,您需要在 client.UploadDataAsync(uri, postArray) 之前使用 await 关键字。因此应该是“await client.UploadDataAsync(uri, postArray);”

其次,由于您在方法中使用了 await 关键字,因此您需要在方法声明和 Task 的开头编写异步而不是 bool。因此它应该是 async public Task StartDownstream(){..}

在这两个步骤之后,由于您的 StardDownstream 方法异步,您也应该等待它。 像 await Downstream1.StartDownstream(); 一样使用它

如果我有任何错误,请告诉我,因为我是这个主题的新手。

【讨论】:

猜你喜欢
  • 2020-03-26
  • 1970-01-01
  • 2018-02-11
  • 2013-06-08
  • 1970-01-01
  • 1970-01-01
  • 2019-11-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多