-1

我写了一个下载网页的功能:功能如下:

public string GetWebPage(string sURL)
    {
        System.Net.WebResponse objResponse = null;
        System.Net.WebRequest objRequest = null;
        System.IO.StreamReader objStreamReader = null;
        string sResultPage = null;
        try
        {
            objRequest = System.Net.HttpWebRequest.Create(sURL);
            objResponse = objRequest.GetResponse();
            objStreamReader = new System.IO.StreamReader(objResponse.GetResponseStream());
            sResultPage = objStreamReader.ReadToEnd();
            return sResultPage;
        }
        catch (Exception ex)
        {
            return "";
        }
    }

但我的问题是。当这个功能在那个时候工作的应用程序转到冻结(不响应)并且那个时候我不能做任何事情。我怎么解决这个问题。下载时用户可以在我的应用程序中做其他事情。

4

2 回答 2

0

欢迎来到阻塞 IO 的世界。

考虑以下:

您希望您的程序下载一个网页,然后返回它在源 html 中找到的前 10 个字母。您的代码可能如下所示:

...
string page = GetWebPage("http://example.com"); // download web page
page = page.Substring(0, 10);
Console.WriteLine(page);
....

当您的程序调用 GetWebPage() 时,它必须等待网页完全下载,然后才能尝试调用 Substring() - 否则它可能会在实际下载字母之前尝试获取子字符串。

现在考虑你的程序。你有很多代码——可能是一个 GUI 界面正在运行——而且它一次一行地执行一条指令。当您的代码调用 GetWebPage() 时,它不可能继续执行其他代码,直到该请求完全完成。您的整个程序正在等待该请求完成。

这个问题可以通过几种不同的方式来解决,最好的解决方案取决于你对代码所做的事情。理想情况下,您的代码需要异步执行。c# 有可以为您处理很多此类问题的方法,但无论哪种方式,您都需要开始一些工作 - 下载您的情况下的网页 - 然后继续执行代码,直到您的主线程收到通知网页已完全下载。然后你的主线程可以开始解析返回值。

我假设既然您已经问过这个问题,那么您通常对线程和并发非常陌生。你有很多工作要做。这里有一些资源供您阅读有关 C# 中的线程和实现并发的信息:

C#线程介绍

.NET 异步 IO 设计

于 2012-10-08T05:48:37.367 回答
0

最好的是使用线程

new Thread(download).Start(url);

如果您的下载页面很大,请使用块逻辑。

HttpWebRequest ObjHttpWebRequest = (HttpWebRequest)HttpWebRequest.Create(Convert.ToString(url));
                ObjHttpWebRequest.AddRange(99204);
                ObjHttpWebRequest.Timeout = Timeout.Infinite;
                ObjHttpWebRequest.Method = "get";
                HttpWebResponse ObjHttpWebResponse = (HttpWebResponse)ObjHttpWebRequest.GetResponse();
                Stream ObjStream = ObjHttpWebResponse.GetResponseStream();
                StreamReader ObjStreamReader = new StreamReader(ObjStream);
                byte[] buffer = new byte[1224];
                int length = 0;

                while ((length = ObjStream.Read(buffer, 0, buffer.Length)) > 0)
                {
                    downloaddata += Encoding.GetEncoding(936).GetString(buffer);
于 2013-09-11T13:31:42.180 回答