0

我从网址收到 连续的 [不间断] 消息:

    string webUrl = "xxxxx/status.cgi";
    WebClient client = new WebClient();
    client.Credentials = new NetworkCredential("UUU", "PPP");

    StreamReader reader = new StreamReader(client.OpenRead(webUrl), Encoding.UTF8,true);
    string line;
    int counter = 0;
    while ((line = reader.ReadLine()) != null)
    {
        if( line == "XXXXXX")
        {
           break;
        }
    }


    Console.WriteLine("Try to Close Stream Reader...");
    reader.Close();
    Console.WriteLine("Stream Reader is closed...");

问题是当我从while循环中中断时,我想关闭流阅读器......但是流阅读器没有关闭......“reader.Close();” 挂起/阻止代码...

为什么会这样?如何解决?

更新:“使用”在我的情况下不起作用:退出循环但流读取器未处理...挂起/阻止

using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Linq;
using System.Text;

namespace TestStreamReader
{
    class Program
    {
        static void Main(string[] args)
        {
            string  webUrl = "http://X.Y.Z:7000/status.cgi";
            int counter = 0;

            using (WebClient client = new WebClient())
            {
                client.Credentials = new NetworkCredential("admin", "000000");

                using (StreamReader reader = new StreamReader(client.OpenRead(webUrl), Encoding.UTF8, true))
                {
                    string line;
                    while ((line = reader.ReadLine()) != null)
                    {
                        counter++;

                        Console.WriteLine("Input"+ line);

                        if (counter == 10)
                        {
                            Console.WriteLine("I am exiting the loop");
                            break;
                        }


                    }

                    Console.WriteLine("Exit the while loop");

                }

                Console.WriteLine("Reader should be desposed");
            }

            Console.WriteLine("Web Client should be disposed!");



        }
    }
}
4

4 回答 4

1

我遇到了同样的问题,但是这个帖子中提出的建议都没有对我有帮助。但我能够以不同的方式修复它,所以我想我会分享......

我使用异步版本client.OpenRead(uri)打开流,然后client.CancelAsync()在需要关闭它时可以调用。那里的实现必须以StreamReader不同的方式处理,因为它是这样工作的。

于 2014-04-16T15:42:45.227 回答
0

我这边的一个快速想法,尝试将 StreamReader 放入 Using。

        string webUrl = "http://www.google.com";
        using (WebClient client = new WebClient())
        {
            client.Credentials = new NetworkCredential("UUU", "PPP");

            int counter = 0;

            using (StreamReader reader = new StreamReader(client.OpenRead(webUrl), Encoding.UTF8, true))
            {
                string line;
                while ((line = reader.ReadLine()) != null)
                {
                    if (line == "XXXXXX")
                    {
                        break;
                    }
                    counter++;
                }

            }
        }

        Console.WriteLine("Try to Close Stream Reader...");
        Console.WriteLine("Stream Reader İSclosed...");

这将使 Connection 保持打开状态,直到不再使用。之后将自动调用 Dispose()。无需手动分离或关闭。[更新] 我还将 WebClient 移动到使用 StreamReaders 之外的使用和计数器变量中。

[编辑]
由于评论,问题看起来像(未经测试的推测)WebClient 的副作用无法退出,因为它看不到流的结尾。因此,StreamReader 等待。我附上了另一种从网络请求中读取的方法。然而,这远非肯定会更好。

    string webUrl = "http://www.google.com";

    HttpWebRequest req = (HttpWebRequest)WebRequest.Create(webUrl);
    req.Credentials = new NetworkCredential("UUU", "PPP");
    using (HttpWebResponse resp = (HttpWebResponse)req.GetResponse())
    {
        using (Stream stream = resp.GetResponseStream())
        {
            int read;
            string line;

            byte[] data = new byte[4096];
            while ((read = stream.Read(data, 0, data.Length)) > 0)
            {
                line = Encoding.GetEncoding("ASCII").GetString(data, 0, data.Length);

                if (line.Contains("(function(){try{var a=window.gbar;"))
                {
                    Console.WriteLine("End Bit founded..");
                    // Some more logic?
                    break;
                }
                data = new byte[4096];
                Console.WriteLine(line);
            }
        }
    }
    Console.WriteLine("End of Stream");

请注意,我在这里使用了 Stream 并手动拆分为 4096 个数据块,只是为了解决问题。通常是using (StreamReader stream2 = new StreamReader(resp.GetResponseStream())) { string test = stream2.ReadToEnd(); }.

希望它能更进一步。
另请注意,上面的编码设置为“ASCII”。

于 2012-07-31T14:23:26.073 回答
0

您是否考虑过使用 HttpWebRequest 并获取响应流,而不是使用 WebClient?

//using System.Net;

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(ApiProcedure.FunctionUri);
    request.Credentials = (CredentialCache)Credentials;
    request.PreAuthenticate = true;

    //define the type of request
    request.Method = HttpMethod;
    request.ContentType = "application/json";

    //execute
    StreamReader sr = new StreamReader(response.GetResponseStream());
    return sr.ReadToEnd();

我知道你正在做一个连续的流,但你应该能够像在你的例子中那样正常对待流阅读器。我认为这种方法会给你更多的控制。

如果我需要执行一个简单的任务,我通常只使用 WebClient,其中所有的细节设置/流都为我完成。发现单独管理请求和响应时我会得到更好的结果。

祝你好运!

编辑:另外,这只是我的代码的一个片段。您可能想看看这里:C# - 如何通过 HTTP 读取连续的 XML 流,这是读取连续数据块的一个很好的例子。

于 2012-07-31T16:22:15.660 回答
0

我见过类似的东西。问题是它正在等待 ReadTimeOut 发生。您可以尝试将 Stream.ReadTimeOut 属性设置为足够小的值。

于 2014-02-20T19:18:09.660 回答