1

IP カメラへの HTTP リクエストを行うアプリケーションを実行しています。HTTP リクエストを実行するたびに、画面に描画される画像を受け取ります。このプロセスはすべて次のように行われます。

  1. 500ミリ秒ごとに呼び出されるタイマーがあります。
  2. タイマーのコードは、http 要求を行うスレッドを呼び出します。

そのため、タイマーが呼び出されたときに http 要求が完全に完了していない可能性が高く、それで問題ありません。

問題は、不明な理由で、「操作がタイムアウトしました」という例外が発生することです。というわけで、操作のログをとりました。http リクエストの前と後の時間をログに記録します。常に約 300 ~ 400 ミリ秒です。例外のログも記録しましたが、ログに記録された時間が 24 ミリ秒または 76 ミリ秒であることに大きな驚きを覚えました。タイムアウトは 5000 ミリ秒に設定されているため、タイムアウトすることはありません。

私のすべてのテストで、ログに記録された時間が 800 ミリ秒を超えたことは一度もありませんでした。これは、設定されたタイムアウトをはるかに下回っています。

「操作がタイムアウトしました」というエラーを説明できる他の理由はありますか? 私も試してみServicePointManager.DefaultConnectionLimit = 200;ますが、何も変わりません。

どうもありがとう!

これがスレッド化されたコードです。ListTest はロガーで、各行がファイルに出力されます。

StructTakePicture structTP = (StructTakePicture)structTakePicture;
ServicePointManager.DefaultConnectionLimit = 200; 
string strFileName = structTP.FolderGUID + "input" + GetNumeroPhoto(structTP.Cam.ID, structTP.NumPhoto) + ".jpg";
DateTime dateDebut = DateTime.Now;
try
{
    ListTest.Add(strFileName + " --- BEGIN : " + dateDebut.ToString()); 

    WebRequest WebRequestObject = HttpWebRequest.Create(String.Format("http://{0}/mjpg/snapshot.cgi?camera={1}", structTP.Cam.TotalIP, structTP.Cam.View));
    WebRequestObject.Timeout = 5000;
    WebRequestObject.Credentials = new NetworkCredential("admin", "admin");
    HttpWebResponse ResponseObject = (HttpWebResponse)WebRequestObject.GetResponse();

    string strTypeRetour = ResponseObject.ContentType;

    if (strTypeRetour == "image/jpeg")
    {
        MemoryStream memoryStream = new MemoryStream(0x10000);

        using (Stream responseStream = WebRequestObject.GetResponse().GetResponseStream())
        {
            byte[] buffer = new byte[0x1000];
            int bytes;
            while ((bytes = responseStream.Read(buffer, 0, buffer.Length)) > 0)
            {
                memoryStream.Write(buffer, 0, bytes);
            }

            ResponseObject.Close();
        }

        byte[] response = memoryStream.ToArray();
        Image img = byteArrayToImage(response);


        img.Save(strFileName);
        structTP.StopEverything = false;
        DateTime dateFin = DateTime.Now;
        TimeSpan span = dateFin.Subtract(dateDebut);
        ListTest.Add(strFileName + " --- TOTALTIME:" + span.Milliseconds.ToString());
        ListTest.Add(strFileName + " --- END : " + dateFin.ToString());
    }
}
catch (System.Net.WebException err)
{
    structTP.StopEverything = true;
    DateTime dateFin = DateTime.Now;
    TimeSpan span = dateFin.Subtract(dateDebut);
    ListTest.Add(strFileName + " === ERROR :" + span.Milliseconds + " | " + err.Message);
}

* 編集 *

コメントに答えるために、私が得るエラーは System.Net.WebException にあり、err.Message は「操作がタイムアウトしました」です。

*編集2 *

これは、コードで行ったログの一部です。ご覧のとおり、タイムアウトは非常に短い応答時間で受信されます。

C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input1_00013.jpg --- BEGIN : 2011-10-27 08:16:46
    C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input1_00010.jpg --- TOTALTIME:353
    C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input1_00010.jpg --- END : 2011-10-27 08:16:47
    C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input2_00006.jpg --- TOTALTIME:610
    C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input2_00006.jpg --- END : 2011-10-27 08:16:47
    C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input2_00008.jpg --- BEGIN : 2011-10-27 08:16:47
    C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input1_00014.jpg --- BEGIN : 2011-10-27 08:16:47
    C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input2_00009.jpg --- BEGIN : 2011-10-27 08:16:47
    C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input2_00005.jpg --- TOTALTIME:996
    C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input2_00005.jpg --- END : 2011-10-27 08:16:48
    C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input2_00004.jpg --- TOTALTIME:800
    C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input2_00004.jpg --- END : 2011-10-27 08:16:48
    C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input1_00007.jpg === ERROR :22 | The operation has timed out
    C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input1_00015.jpg --- BEGIN : 2011-10-27 08:16:48
    C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input1_00014.jpg --- TOTALTIME:391
    C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input1_00014.jpg --- END : 2011-10-27 08:16:49
    C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input1_00009.jpg === ERROR :23 | The operation has timed out
    C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input2_00008.jpg --- TOTALTIME:526
    C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input2_00008.jpg --- END : 2011-10-27 08:16:50
    C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input1_00012.jpg --- TOTALTIME:461
    C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input1_00012.jpg --- END : 2011-10-27 08:16:50
    C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input1_00015.jpg --- TOTALTIME:780
    C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input1_00015.jpg --- END : 2011-10-27 08:16:50
    C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input1_00011.jpg --- TOTALTIME:49
    C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input1_00011.jpg --- END : 2011-10-27 08:16:50
    C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input2_00009.jpg --- TOTALTIME:133
    C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input2_00009.jpg --- END : 2011-10-27 08:16:50
    C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input2_00007.jpg --- TOTALTIME:140
    C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input2_00007.jpg --- END : 2011-10-27 08:16:51
    C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input1_00013.jpg === ERROR :28 | The operation has timed out
    C:\Users\jfcote\AppData\Local\Temp\d1785720-afc6-4822-b02d-fdf6d2f2c0d1\input2_00010.jpg --- BEGIN : 2011-10-27 08:16:56
4

1 に答える 1

5

設定するTimeout値は、GetResponseが応答するまでの時間です。には、読み取りまたは書き込み時に使用されるReadWriteTimeoutHttpWebRequestもあります。を設定していないため、タイムアウト内に戻っている可能性がありますが、読み取りはタイムアウトしています。ReadWriteTimeoutGetResponse

次の変更を試すことをお勧めします。

HttpWebRequest WebRequestObject = (HttpWebRequest)HttpWebRequest.Create(String.Format("http://{0}/mjpg/snapshot.cgi?camera={1}", structTP.Cam.TotalIP, structTP.Cam.View));
WebRequestObject.Timeout = 5000;
WebRequestObject.ReadWriteTimeout = 5000;

追加の観察:

ログが不完全です。たとえば、 fileinput1_0007に ERROR がありますが、 BEGIN 行がありません。あなたListTestのコレクションはスレッドセーフですか? そうでない場合、2 つのスレッドが同時にそれを更新すると、リストが破損する可能性があります。

また、あなたのコードは 500 ミリ秒ごとにリクエストを行っていると言いました。しかし、ログには 1 秒間に 3 つのリクエストが表示されます。

確かに、未処理のリクエストが多すぎるために何らかの理由で、ServicePointManagerまたは他の何かがそれを強制終了することを決定しない限り、それはタイムアウトを説明しません。例外スタック トレースを見て、タイムアウト例外がスローされた場所を確認できます。

また、最初のリクエストが完了するまでカメラに別のリクエストを送信しないように、コードを変更することを検討することもできます。したがって、500 ミリ秒ごとに起動するタイマーの代わりに、500 ミリ秒の遅延でワンショット タイマーを開始します。タイマー コールバックは画像​​を取得し、タイマーをさらに 500 ミリ秒間再初期化します。このようにして、画像に対する未解決のリクエストが複数存在することはなく、奇妙な同時実行の問題を回避できます。現在のところ、写真が順不同で表示される可能性があります。

同時実行の問題があると思います。複数のスレッドがこのコードを同時に実行できる場合 (可能であることを示しました)、ListTest何らかのスレッドセーフなリストでない限り、破損する可能性があります。

于 2011-10-26T20:29:06.247 に答える