异步WebClient不是真正的异步?

时间:2011-02-07 20:44:12

标签: c# multithreading asynchronous webclient

我在类中创建了一个异步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);方法上。

3 个答案:

答案 0 :(得分:3)

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

感谢您的回答!

答案 1 :(得分:0)

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

答案 2 :(得分:-1)

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

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

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

如果我有任何错误,请告诉我,因为我对这个话题不熟悉。