0

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...");

問題は、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

WebClient を使用する代わりに、HttpWebRequest を使用して応答ストリームを取得することを考えたことはありますか?

//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 (データの連続チャンクを読み取る良い例)。

于 2012-07-31T16:22:15.660 に答える
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...");

これにより、接続が使用されなくなるまで開いたままになります。その後、 Dispose() が自動的に呼び出されます。手動で取り外したり閉じたりする必要はありません。[更新] また、WebClient を using に移動し、カウンター変数を StreamReaders using の外に移動します。

[編集]
コメントにより、問題は (テストされていない憶測) WebClient の副作用のように見えます。これは、ストリームの終わりが見えないためです。したがって、StreamReader は待機します。Web リクエストから読み取る別の方法を添付します。ただし、これが確実にうまくいくとは限りません。

    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");

ここでストリームを使用し、問題のために手動で 4096 データブロックに分割したことに注意してください。通常はusing (StreamReader stream2 = new StreamReader(resp.GetResponseStream())) { string test = stream2.ReadToEnd(); }.

それがさらに一歩を踏み出すことを願っています。
上記のエンコーディングが「ASCII」に設定されていることにも注意してください。

于 2012-07-31T14:23:26.073 に答える