无法关闭StreamReader(reader.Close();阻止代码)

时间:2012-07-31 14:18:02

标签: c# .net webclient streamreader

我从网址获得连续 [不停]的消息:

    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 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

一个简单的想法,尝试将StreamReader放入使用。

        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外部的using和counter变量

[编辑]
由于评论问题看起来像(未经测试的)推测,WebClient的副作用无法退出,因为它无法看到流的结束。因此,StreamReader等待。我附上另一种从webrequest读取的方法。然而,这远远不能确保更好的工作。

    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”。

答案 2 :(得分: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# - How to read a continuous stream of XML over HTTP以获取读取连续数据块的良好示例。

答案 3 :(得分:0)

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