当我尝试获取URL的内容时应用程序冻结

时间:2012-06-26 22:38:04

标签: c# http

首先看我的源代码:

WebClient client = new WebClient();
String url = "http://localhost";
client.Headers.Add("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)");
try
{
    Stream data = client.OpenRead(url);
    if (data == null)
        throw new WebException("Cannot browse the url...");
    StreamReader reader = new StreamReader(data);
    string s = reader.ReadToEnd();
    textBox1.Text = s;
    data.Close();
    reader.Close();

}
catch (Exception ex)
{
    MessageBox.Show(ex.Message);
}  

当我运行我的应用程序时,它将在此操作的持续时间内冻结 我的代码中哪一部分错了?

2 个答案:

答案 0 :(得分:5)

  

我的代码中哪一部分错了?

在UI线程中执行阻止网络操作的部分。当您的UI线程被阻止等待响应时,控件无法重新绘制,您的UI无法响应事件。

您应该在后台线程中执行此操作,然后使用Control.Invoke(WinForms)或Dispatcher.Invoke(WPF)将回调编组回UI线程。有关详细信息,请参阅Joe Albahari's threading guide

或者,使用WebClient上的异步操作。

答案 1 :(得分:2)

它会回归吗?我确定它可能会发生,因为如果传递了无效的URI,OpenRead将抛出异常。来自文档:

  

OpenRead方法创建一个Stream实例,用于读取address参数指定的资源的内容。 此方法在打开流时阻止。要在等待流时继续执行,请使用OpenReadAsync方法之一。

OpenRead是同步的,即它阻止当前线程,直到它返回所有数据。如果您希望异步执行读取,请使用OpenReadAsync

当您调用此方法时,操作将开始,但您的代码将继续。当操作完成时,将调用一个回调方法(其OpenReadCompleted事件的处理程序)来处理响应。