C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[19]: どんな例外が考えられるか


(過去ログ 148 を表示中)

[トピック内 20 記事 (1 - 20 表示)]  << 0 >>

■86487 / inTopicNo.1)  どんな例外が考えられるか
  
□投稿者/ kiku (23回)-(2018/02/05(Mon) 20:29:36)

分類:[.NET 全般] 

環境
C# WindowsFormアプリ

Move中にファイルをオープンする場合にどんな例外が発生する可能性がありますでしょうか?

アプリ1(PC1)では、下記のようにローカルフォルダにあるcsvファイルを
PC2の共有フォルダに、拡張子tmpでコピーしてから、
tmpからcsvへリネーム(move)しています。

一方、PC2で動作しているアプリ2では、
PC2上にある共有フォルダ内にあるCSVファイルを
リードしている状況になります。
このリード中に例外が発生しましたが、
例外を握り潰していたため、どんな例外が発生したかは
わからない状況です。
どんな例外が発生する可能性があるでしょうか?

1日に1回程度発生し、どうして発生するかわからない状況です。
通常は問題なくファイルオープンできているため、
リネーム中にファイルをオープンすると発生することがあるのでは
ないかと想像していますが
例外を握り潰しているため、詳細がわかりません。

理論上、どんな例外が発生するでしょうか?
当方では発生しないはずとしてコーディングしています。


●アプリ1
        string DIR = Path.Combine("PC1のローカルフォルダのパス", "csv");
        var localfile = Directory.GetFiles(DIR, "*", SearchOption.TopDirectoryOnly);
        var filelist = localfile.Where(x => Regex.IsMatch(Path.GetFileName(x), @"^.*\.csv$", RegexOptions.IgnoreCase));
        filelist.OrderBy(x => x);
        foreach(var f in filelist)
        {
            var filename = Path.GetFileNameWithoutExtension(f);
            var tmpfilename = Path.Combine("PC2の共有フォルダのパス", filename + ".tmp");
            var csvfilename = Path.Combine("PC2の共有フォルダのパス", filename + ".csv");
            try
            {
                File.Copy(f, tmpfilename, true);
                if (File.Exists(csvfilename))
                {
                    continue;
                }
                File.Move(tmpfilename, csvfilename);
                File.Delete(f);
            }
            catch (Exception ex)
            {
                continue;
            }
        }

●アプリ2
	    var localfile = Directory.GetFiles("PC2の共有フォルダのパス", "*", SearchOption.TopDirectoryOnly);
	    var filelist = localfile.Where(x => Regex.IsMatch(Path.GetFileName(x), @"^.*\.csv$", RegexOptions.IgnoreCase));
	    filelist.OrderBy(x => x);
	    foreach(var f in filelist)
	    {
	            try
	            {
	                var ret = Read_f(f);
	                if (!ret)
	                {
	                    throw new Exception("ファイル読取エラー");
	                }
	            }
	            catch (Exception ex)
	            {
					●ここで例外発生したが、Exceptionを握り潰していたためどんな例外かわからない。
	            }
	    }

        private void Read_f(string filename)
        {
            using (var sr = new StreamReader(filename, Encoding.UTF8))
            {
                while (!sr.EndOfStream)
                {
                    var line = sr.ReadLine();
                }
                sr.Close();
            }
        }


引用返信 編集キー/
■86488 / inTopicNo.2)  Re[1]: どんな例外が考えられるか
□投稿者/ あまみ (1回)-(2018/02/06(Tue) 08:50:29)
C#にはキャッチした例外をvb.netのようにex.Messageでエラー内容を表示するのがありませんでしたっけ?
調べてみたらC#でも使えるみたいなんでMsgBoxで見てみたらどうでしょうか。
引用返信 編集キー/
■86489 / inTopicNo.3)  Re[2]: どんな例外が考えられるか
□投稿者/ とっちゃん (484回)-(2018/02/06(Tue) 10:38:12)
No86487 (kiku さん) に返信

> 理論上、どんな例外が発生するでしょうか?
> 当方では発生しないはずとしてコーディングしています。

理論上ということであれば、ディスク操作しているので、ディスクエラー関連の例外は一通り配慮が必要だと思います。
アプリ2はリードのみ(ただしアプリ1側は別)なのでディスクフルは出ないと思いますが。。。

また、よくあるエラーの一つにアンチウィルスソフトがアクセスしていたためアクセスに失敗というのもあります。
パッケージベンダーさんだと大体年に一度くらいはこのネタでサポートがにぎわうくらいにはメジャーです。

そのほかではハードウェアエラーの類がありますね。セクタが読めなくてリードエラーもよくある話題の一つです。

その他、ソースに記述していない処理の部分で例外が出る可能性もあります。
ReadLine() 部分は読み捨てているソースとなっていますが、実際にはそこで何かしていると思います。
その何かの処理中にメモリ不足などが発生すれば例外が発生します。UTF8のつもりで読んでいるのに保存しているのは
Shift-JISだと、ASCII以外の文字コードで文字化けするため、それが理由でエラーになるなどもあります。

理論上という意味でいえば、ほかにも例外は出る可能性がありますが、ソースコードの全文があるわけではないので
これ以上は何とも言えません。

あと、本題とは関係ありませんが

filelist.OrderBy(x => x);

では、OrderBy の結果が使われません。言い換えれば無駄な処理を呼び出している状態といえます。

これが、

var filelist = localfile.Where(x => Regex.IsMatch(Path.GetFileName(x), @"^.*\.csv$", RegexOptions.IgnoreCase)).OrderBy(x => x);

であればまた違ってきますが...

それと、拡張子を絞りたいだけなら、GetFiles のパラメータで指定するという方法もあります。
また、Path.GetFileName() ではなく、Path.GetExtension() を使えば、拡張子だけ取得できます。


さて、理論上発生しうる例外という点ではほかにもあるかもしれませんが
ソースコードが修正可能なのであれば、例外を無条件に握りつぶすのではなく
ログを取得しておくなど、あとで確認できる方法をとることはできないのでしょうか?

ex.Message だけでもかなりの判断が可能と思いますが、ex.ToString() でトレースも含めて詳細を
吐き出しておくことでより詳しく調査することができます。

引用返信 編集キー/
■86490 / inTopicNo.4)  Re[3]: どんな例外が考えられるか
□投稿者/ kiku (24回)-(2018/02/06(Tue) 12:54:35)
なんだかわからない状況で、
ご回答頂きありがとうございます。

例外をログに吐き出していれば
そこから原因を追究することが出来るのですが
お客様先で稼働しているアプリなので
原因を説明しないと、アプリを入れ替えることも出来ない状況にあります。

お客様へ説明し、原因追及のため、ログを追加したアプリに
入れ替えさせてほしいと依頼する方向で進めます。

ちなみにアプリ1でリネーム中(move。tmpからcsvへ)に
アプリ2でDirectory.GetFilesにてCSVファイル名一覧を取得し、
アプリ2で読取を行うことはあるのでしょうか?
moveが完了しないと、Directory.GetFilesにてリネーム後のcsvは
取得できないと考えています。


引用返信 編集キー/
■86491 / inTopicNo.5)  Re[4]: どんな例外が考えられるか
□投稿者/ なちゃ (235回)-(2018/02/06(Tue) 15:13:07)
定義ではRead_fは戻り値無しですが、呼び出し側では戻り値でエラーチェックしています。
実際のコードがどうなっているか分かりませんが、Read_f側ですでに握りつぶしている可能性もありますので注意してください。

調査に関しては、例外のログを加える事を許可もらう方が早いでしょうしいいでしょう。
ただ、例外は分かっても原因は分からない可能性はあります。
短時間で少数回のリトライ処理などは入れた方がよいだろうと思います。

あと、例外が発生したと分かったのはなぜですか?
例外が発生してるのは確実ですか?
見たところ例外が発生したことも確認できないコードに思えるので。
引用返信 編集キー/
■86492 / inTopicNo.6)  Re[5]: どんな例外が考えられるか
□投稿者/ kiku (25回)-(2018/02/06(Tue) 18:18:11)
No86491 (なちゃ さん) に返信
> 定義ではRead_fは戻り値無しですが、呼び出し側では戻り値でエラーチェックしています。
> 実際のコードがどうなっているか分かりませんが、Read_f側ですでに握りつぶしている可能性もありますので注意してください。

承知致しました。

> 調査に関しては、例外のログを加える事を許可もらう方が早いでしょうしいいでしょう。
> ただ、例外は分かっても原因は分からない可能性はあります。
> 短時間で少数回のリトライ処理などは入れた方がよいだろうと思います。

サンプルアプリを作ろうと思います。

> あと、例外が発生したと分かったのはなぜですか?
> 例外が発生してるのは確実ですか?
> 見たところ例外が発生したことも確認できないコードに思えるので。

掲載したソースでは、省いておりますが、
実際には例外をキャッチし、ログを取得しています。
しかし、ログの内容が「e.ToString()」を記述していないため
キャッチしても例外内容がわからない状況になっています。
なので確実に例外が発生しています。


引用返信 編集キー/
■86493 / inTopicNo.7)  Re[6]: どんな例外が考えられるか
□投稿者/ とっちゃん (485回)-(2018/02/06(Tue) 18:46:00)
No86492 (kiku さん) に返信
> 掲載したソースでは、省いておりますが、
> 実際には例外をキャッチし、ログを取得しています。
> しかし、ログの内容が「e.ToString()」を記述していないため
> キャッチしても例外内容がわからない状況になっています。
> なので確実に例外が発生しています。
>
>
例外が発生していることがわかっているということは、理論上の話ではなく
現実のエラーからわかることは何か?トラブルシュートするにはどうすればいいか?
なのではないでしょうか?

引用返信 編集キー/
■86509 / inTopicNo.8)  Re[7]: どんな例外が考えられるか
□投稿者/ kiku (26回)-(2018/02/07(Wed) 13:17:04)
No86493 (とっちゃん さん) に返信
> 例外が発生していることがわかっているということは、理論上の話ではなく
> 現実のエラーからわかることは何か?トラブルシュートするにはどうすればいいか?
> なのではないでしょうか?

失礼しました。「理論上」という言葉が悪かったかと思います。
実際に例外が発生しているが、その例外内容がわからない状況です。
そこでその例外がどんな例外か想定できないかということがご質問になります。
それが想定できれば、対処方法もわかってくると思っています。
引用返信 編集キー/
■86514 / inTopicNo.9)  Re[8]: どんな例外が考えられるか
□投稿者/ とっちゃん (486回)-(2018/02/07(Wed) 15:29:36)
No86509 (kiku さん) に返信
> ■No86493 (とっちゃん さん) に返信
>>例外が発生していることがわかっているということは、理論上の話ではなく
>>現実のエラーからわかることは何か?トラブルシュートするにはどうすればいいか?
>>なのではないでしょうか?
>
> 失礼しました。「理論上」という言葉が悪かったかと思います。
> 実際に例外が発生しているが、その例外内容がわからない状況です。
> そこでその例外がどんな例外か想定できないかということがご質問になります。
> それが想定できれば、対処方法もわかってくると思っています。

例外が発生していることは把握しているんですよね?
ログのようなものをとっているみたいですが、そこからわかることはないのでしょうか?
throw new Exception("ファイル読取エラー");
の例外ログしか残っていないということでしょうか?

なんにしても、Read_f の実装が異なる(戻り値がないのになにか受け取っている)ので
現状のソースから見えるものと言ったら、Read_f の中身くらいと思いますが
提示のソースからは
StreamReaderのコンストラクタ
EndOfStream プロパティ
ReadLine メソッド
はそれぞれ例外を投げるか?投げるとすればどのような例外か?

程度になると思います。
いずれも、リファレンス(VS上でソースの該当位置にカーソルを置いてF1を押せばでる)を見れば、どんな例外を投げるか出ていますが
それでは足りない(もしくはそれとは異なる例外が出ている)ということですかね?

引用返信 編集キー/
■86634 / inTopicNo.10)  Re[9]: どんな例外が考えられるか
□投稿者/ kiku (29回)-(2018/02/23(Fri) 17:55:35)
その後進展がありましたのでご報告させて頂きます。
ログを強化したアプリにて、現象が再現し、
下記のような例外が発生していることがわかりました。

アプリ2での例外
System.IO.StreamReaderにて
別のプロセスで使用されているため、プロセスはファイル '*****' にアクセスできません。
System.IO.IOException: 別のプロセスで使用されているため、プロセスはファイル '*****' にアクセスできません。

これから考えられることは、
アプリ1のMove命令でファイルがロックしているというように思ったのですが
認識違いはありますのでしょうか?
Move命令はロックしないと思っていたのですが。。。。

引用返信 編集キー/
■86642 / inTopicNo.11)  Re[10]: どんな例外が考えられるか
□投稿者/ 渋木宏明(hidori) (1回)-(2018/02/25(Sun) 07:19:34)
> Move命令はロックしないと思っていたのですが。。。。

ファイルシステムまたいでたら無理でしょ。

引用返信 編集キー/
■86643 / inTopicNo.12)  Re[11]: どんな例外が考えられるか
□投稿者/ kiku (30回)-(2018/02/25(Sun) 09:15:21)
No86642 (渋木宏明(hidori) さん) に返信
>>Move命令はロックしないと思っていたのですが。。。。
>
> ファイルシステムまたいでたら無理でしょ。

やっぱりそうなんですね。
事実を受け入れるように致します。

対処方法ですが、
他プロセスが利用中であるか、そうでないか例外によって判断し、
処理を分けることを考えています。

System.IO.StreamReaderにおけるIOExceptionは、
他プロセスが利用中のみ発生するのでしょうか?
それとも他の要因も考えられるのでしょうか?

引用返信 編集キー/
■86644 / inTopicNo.13)  Re[12]: どんな例外が考えられるか
□投稿者/ Azulean (922回)-(2018/02/25(Sun) 09:22:18)
No86643 (kiku さん) に返信
> System.IO.StreamReaderにおけるIOExceptionは、
> 他プロセスが利用中のみ発生するのでしょうか?
> それとも他の要因も考えられるのでしょうか?

ほかの要因もあり得ますし、IOException はそれを継承した例外クラスがほかにもありますので、IOException で catch するだけでは不十分です。

https://msdn.microsoft.com/ja-jp/library/system.io.ioexception の 継承階層 を参照。
引用返信 編集キー/
■86645 / inTopicNo.14)  Re[13]: どんな例外が考えられるか
□投稿者/ kiku (31回)-(2018/02/25(Sun) 09:37:01)
> ほかの要因もあり得ますし、IOException はそれを継承した例外クラスがほかにもありますので、IOException で catch するだけでは不十分です。
> ※ https://msdn.microsoft.com/ja-jp/library/system.io.ioexception の 継承階層 を参照。

ありがとうございます。
やはりそうなのですね。
階層構造を見てみました。
発生しうる例外は下記になると思いました。

System.IO.DriveNotFoundException
System.IO.EndOfStreamException
System.IO.FileLoadException
System.IO.FileNotFoundException
System.IO.PathTooLongException
System.IO.PipeException

System.IO.StreamReaderを実行する前に、事前検証をしているため、
この中で現実的に発生するのは、下記であると考えました。

System.IO.FileLoadException

これをキャッチしすれば判定できるという理解で正しいでしょうか?
現象が容易に再現すれば、何度も発生させて検証できるのですが
なかなか発生しないため、知見があれば教えてほしいです。

引用返信 編集キー/
■86646 / inTopicNo.15)  Re[14]: どんな例外が考えられるか
□投稿者/ Azulean (923回)-(2018/02/25(Sun) 15:50:14)
No86645 (kiku さん) に返信
> System.IO.StreamReaderを実行する前に、事前検証をしているため、
> この中で現実的に発生するのは、下記であると考えました。
>
> System.IO.FileLoadException
>
> これをキャッチしすれば判定できるという理解で正しいでしょうか?

StreamReader では発生しないでしょうね、それは。

誤解しているようですが、私が言いたかったのは「catch (IOException) だと、そのクラスを継承した例外クラスも同じようにキャッチしてしまい、狙った例外だけを捉えることができない」ということです。
また、IOException は「入出力関する汎用的な例外」であり、今回のエラー以外の場合もスローされる恐れはあります。

なので、どういったことをしたいか?によって対応は変わると思います、

1.ファイルがロックされているところだけ狙いたいのか? → catch(IOException) かつエラーコード判定
2.IOException のファイルロック以外のエラーもまとめてキャッチしてかまわないのか? → catch(IOException)
3.あらゆる例外を握りつぶしてリトライしたいのか? → catch(Exception)
引用返信 編集キー/
■86653 / inTopicNo.16)  Re[15]: どんな例外が考えられるか
□投稿者/ kiku (32回)-(2018/02/26(Mon) 13:29:12)
2018/02/26(Mon) 13:38:13 編集(投稿者)

> 誤解しているようですが、私が言いたかったのは「catch (IOException) だと、そのクラスを継承した例外クラスも同じようにキャッチしてしまい、狙った例外だけを捉えることができない」ということです。
> また、IOException は「入出力関する汎用的な例外」であり、今回のエラー以外の場合もスローされる恐れはあります。

なるほど、理解しました。

> なので、どういったことをしたいか?によって対応は変わると思います、
> 1.ファイルがロックされているところだけ狙いたいのか? → catch(IOException) かつエラーコード判定
> 2.IOException のファイルロック以外のエラーもまとめてキャッチしてかまわないのか? → catch(IOException)
> 3.あらゆる例外を握りつぶしてリトライしたいのか? → catch(Exception)

できれば、上記1で判定したいです。
IOExceptionのリファレンスを見たのですが、
HResultプロパティ、Dataプロパティで判定すれば良いのでしょうか?

上記内容をログに出力していないので、それぞれどんな値で判定すべきなのかわかりません。
もう一度再現させる必要があるのかな。辛い。。。
引用返信 編集キー/
■86654 / inTopicNo.17)  Re[16]: どんな例外が考えられるか
□投稿者/ 魔界の仮面弁士 (1577回)-(2018/02/26(Mon) 14:31:00)
No86653 (kiku さん) に返信
> IOExceptionのリファレンスを見たのですが、
> HResultプロパティ、Dataプロパティで判定すれば良いのでしょうか?

.NET Framework のバージョンが 4 以上であれば、
HResultプロパティが使えるかと思います。
http://rucio.cloudapp.net/ThreadDetail.aspx?ThreadId=30283


4 未満の場合は、HResult が public ではなく protected なので、
リフレクションが必要になるかもしれません。
引用返信 編集キー/
■86656 / inTopicNo.18)  Re[17]: どんな例外が考えられるか
□投稿者/ kiku (33回)-(2018/02/26(Mon) 18:22:42)
ご回答ありがとうございます。
この定数を探すことが出来なかったため助かります。
この方法で判定していきたいと思います。

ちなみにどこかにまとまったリファレンスなどあるのでしょうか?
他にどんな定数が定義されているかなど。
引用返信 編集キー/
■86666 / inTopicNo.19)  Re[18]: どんな例外が考えられるか
□投稿者/ kaina (36回)-(2018/02/27(Tue) 09:08:52)
> ちなみにどこかにまとまったリファレンスなどあるのでしょうか?
> 他にどんな定数が定義されているかなど。

魔界の仮面弁士さんの張ったURLの先をたどれば見つかりましたよ?

https://docs.microsoft.com/ja-jp/dotnet/framework/interop/how-to-map-hresults-and-exceptions

返信内容くらいキチンと確認したほうがよいのではないですか?

引用返信 編集キー/
■86668 / inTopicNo.20)  Re[19]: どんな例外が考えられるか
 
□投稿者/ kiku (34回)-(2018/02/27(Tue) 10:27:27)
No86666 (kaina さん) に返信
> 魔界の仮面弁士さんの張ったURLの先をたどれば見つかりましたよ?

魔界の仮面弁士さんは2回投稿されていたんですね。
気が付きませんでした。
2回目の投稿の中にはリンクがたくさん貼られてあり、
大変参考になりました。

ありがとうございました。
以上で解決済みとさせて頂きます。

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -