我从网址获得连续 [不停]的消息:
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!");
}
}
}
答案 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属性设置为足够小的值。