質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

2回答

1064閲覧

C# 離れた場所での例外処理はできるのかどうか

Reindeer_Csharp

総合スコア13

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2022/09/02 00:43

編集2022/09/02 01:32

前提

C#を書いているうちにふと思ったのでできるのかどうか試行錯誤しながら質問させていただきます。

実現したいこと

・別フォームから例外を取得して、例外処理を行う。

本来の例外処理の骨組み

C#

1private void 何かしらのイベント的なあれ() 2{ 3 try 4 { 5 //何かしらの例外発生 6 } 7 catch 8 { 9 return;//例外出たときに処理から外す。 10 }

これは明示的で読みやすいけど似たような処理(マージ不可)が何個もあるとエコな書き方ではないなと思っちゃう。
デザイナー側のコードで例外起きたらどう例外(ライセンス切れなどの例外)を取ろうかも考えてしまう(こっちが本題かも。)

やりたいこと

form1

C#

1private void ~~() 2{ 3 try 4 { 5 //なにかしらの例外が発生する。 6 } 7}

form2

C#

1private void ~~()//多分取得するための変数が必要? 2{ 3 catch 4 { 5   //form1の例外をキャッチする。 6  } 7} 8

前提条件としてはform1を親、form2が子です。
もしこれが実現可能なら複数の例外処理を一つにまとめられるのである程度コードの短縮ができるかなぁと思ってます。
もしできたらすごい便利...かな。
そもそも専用の例外があるかも?

詳しく調べて不可能と分かれば自己回答で質問を閉じさせていただきます。
もしわかる人がいましたら教えてくれると嬉しいです。

補足情報(FW/ツールのバージョンなど)

VisualStudioの最新版 C# .net フォームアプリケーション 最新版

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dodox86

2022/09/02 01:28

> 前提条件としてはform1,2が同時に開かれている状態で、両方アクティブ状態です。 一般に複数のウィンドウ(フォーム)が開いているときに「アクティブ」と言うと、表示されているもののうちどれかひとつが入力可能な状態のものを指します。ここでいうアクティブとは要は、2つのフォームが表示されていることを指していますか? また、Form1からForm2を開くような親子、オーナーの関係ではなく、FormXからForm1、Form2を同時に開くような、Form1とForm2は兄弟の関係、でしょうか。
Reindeer_Csharp

2022/09/02 01:31

>Form1からForm2 親子関係でフォームを開いています。文章修正させていただきます。
dodox86

2022/09/02 01:33

あれ、質問自体終わってしまいましたね。 > もしこれが実現可能なら複数の例外処理を一つにまとめられるのである程度コードの短縮ができるかなぁと思ってます。もしできたらすごい便利...かな。 まぁ、何にせよ目先の便利さに目を奪われて進めると後で保守しづらい役に立たないコードになりがちです。
Reindeer_Csharp

2022/09/02 01:35

>保守しづらい役に立たないコードになりがち たしかにそうですね、明示的な書き方が一番無難ですね。
guest

回答2

0

ベストアンサー

そもそも、よほどのことがない限り try - catch は書かないというのが原則です。その原則に従えばこのスレッドのようなことは考える必要がないかもしれません。

.NET アプリの例外処置について Microsoft Blog に書いてあったことを要約して紹介しておきます(Blog は今はリンク切れです)。

(1) 予測可能で正しい業務フローに戻すことができる「業務エラー」(例:ユーザーの入力間違い)と、予測できないもしくは予測はできても何の対応もできない「例外」(例:DB サーバーダウン)を区別して対処

(2) 「例外」はランタイムに拾わせてアプリケーションを停止させる。 無かったことにして、ユーザが作業を続けられるようにすると、強制的に停止させるより好ましからざる状況に陥るかも(ユーザーが大事なデータを壊したりとか)。

(3) よほどのことがない限り try-catch は書かない。

(4) キャッチせざるを得ない場合でも Execption はキャッチしない。範囲を絞る。例えば DB 関係の例外が予測されるなら SqlException に限定して catch し、Number プロパティなどでエラーの内容を調べて対処するとか。

(5) 間違って補足してしまった例外は throw する。(注:catch ブロックでキャッチした例外を throw するとスタックトレースが途切れるので単に throw と書く)

(6) ユーザーへの通知が必要なら、集約的例外処置を利用する。

それから、.NET 4 からは破損状態例外は catch できなくなっているそうですが、「それでも Catch (Exception e) を使用するのはよくない」ということについては以下の記事を見てください。

破損状態例外を処理する
https://docs.microsoft.com/ja-jp/archive/msdn-magazine/2009/february/clr-inside-out-handling-corrupted-state-exceptions

自分が持っている Microsoft の本に、上に書いた原則に則ったサンプルが載っていたので紹介しておきます。

データベースに INSERT する際に PK 制約違反で発生する例外のみ catch して「業務エラー」(2 重登録)としてユーザーに再入力を促し、その他は再 throw してランタイムに拾わせてアプリケーションを停止させるというものです。

public bool InsertAuthors() { var connection = new SqlConnection("接続文字列"); var command = new SqlCommand("INSERT INTO authors VALUES ('172-32-1176', 'White', ...)", connection); try { connection.Open(); try { command.ExecuteNonQuery(); } catch(SqlException sqle) { if (sqle.Number == 2627) { return false; } else { throw; } } } finally { connection.Close(); } return true; }

以下の記事も参考になると思います。

例外の推奨事項
https://docs.microsoft.com/ja-jp/dotnet/standard/exceptions/best-practices-for-exceptions

投稿2022/09/02 01:24

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Reindeer_Csharp

2022/09/02 01:29

参考にさせていただきます。ありがとうございます。
guest

0

例外処理がログを出すくらいしかないなら、Application.ThreadExceptionあたりで処理すればいいのでは。
https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.forms.application.threadexception

投稿2022/09/02 01:14

matukeso

総合スコア1590

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問