Reputation: 2325
I get continous [ non-stop ] mesages from web url:
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...");
The problem is that when I break from while loop, i want to close the stream reader...But stream reader does not close...."reader.Close();" hangs/block the code...
Why this happen? How to fix it?
UPDATE: "using" DOES NOT WORK IN MY CASE: Exit the loop but stream reader is not disposed...Hang/Block
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!");
}
}
}
Upvotes: 0
Views: 1475
Reputation: 183
I had the same problem, but none of the suggestions made in this thread were helpful for me. But I WAS able to fix it a different way, so I thought I'd share...
I used the asynchronous version of client.OpenRead(uri)
to open the stream, and then I was able to call client.CancelAsync()
when I need to shut it down. The implementation in there must be disposing the StreamReader
differently, because it works that way.
Upvotes: 1
Reputation: 3632
I've seen something similar. The problem is that it's waiting for a ReadTimeOut to occur. You can try setting the Stream.ReadTimeOut property to something sufficiently small.
Upvotes: 0
Reputation: 614
Instead of using WebClient, have you thought about using HttpWebRequest and getting the response stream?
//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();
I know you're doing a continuous stream, but you should be able to treat the stream reader normally like you're doing in your example. I think this method will give you a little more control.
I normally only use WebClient if I need to perform a simple task where all the nitty gritty setup/streams are done for me. Find I get better results when managing the request and response separately.
Good luck!
EDIT: Also, this is just a snippet from my code. You might want to take a look here: C# - How to read a continuous stream of XML over HTTP for a good example of reading continuous chunks of data.
Upvotes: 0
Reputation: 2987
A Quick idea frm my side, try put the StreamReader in a 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...");
This will keep Connection open until it's no longer used. The Dispose() will be called automatically after then. No need of manual detach or close. [Update] I also move the WebClient into a using and the counter variable outside the StreamReaders using.
[Edit]
Due to comments the problem looks like a (untested speculation) side-effect of the WebClient can't quit, because it can't see the end of the stream. Therefore, the StreamReader wait. I attach Another approach to read from a webrequest. However this will far from sure work better.
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");
Please note I used Stream here and manually split to 4096 datablocks, just for the sake of the problem. The usual would be using (StreamReader stream2 = new StreamReader(resp.GetResponseStream())) { string test = stream2.ReadToEnd(); }
.
Hope it will give any step further.
Also mind that Encoding is set to "ASCII" above.
Upvotes: 0