2016-05-19 10 views
0

データベースに対して非同期アクションを実行しているInfoMessageイベントハンドラに登録して、SQLから情報メッセージを取得するクラスAの次のスニペットがあります。クラスBでは 別のクラスのイベントハンドラからの例外のキャッチ

public void BackupDatabase(string DatabaseName, string BackupLocation, bool backupType = true) 
    { 
     //SQL for FULL database backup 
     string SQL = "BACKUP DATABASE [" + DatabaseName + "] TO DISK = N'" + BackupLocation + "\\" + DatabaseName +".bak' WITH FORMAT, NAME = N'" + DatabaseName + "-Full Database Backup', STATS = 1"; 

     using (SqlConnection db_conn = new SqlConnection(ConnectionString)) 
     { 

      UpdateStatusText("Establishing Connection to Database"); 
      db_conn.Open(); 
      db_conn.FireInfoMessageEventOnUserErrors = true; 
      db_conn.InfoMessage += BackupInfoMessages; 

      using (SqlCommand sqlCmd = new SqlCommand(SQL, db_conn)) 
      { 

       sqlCmd.ExecuteNonQuery(); 

      } 
      UpdateStatusText("Backup Complete."); 
     } 
    } 

    private void BackupInfoMessages(object sender, SqlInfoMessageEventArgs e) 
    { 
     foreach (SqlError info in e.Errors) 
     { 
      if(info.Class > 10) 
      { 
       logFile.ExMsg("Exception : " + e.Message); 
       throw new Exception(e.Message); 

      } 
      else 
      { 
       UpdateStatusText(e.Message, 1); 
      } 
     } 
    } 

、私は、メッセージの重大度に応じて、トライキャッチ

try 
{ 
    DBOperations.BackupDatabase("DB","C:\\DBBackup\\DB.bak"); 
} 
catch (Exception ex) 
{ 

    logFile.ExMsg(ex.Message); 
    logFile.ExMsg(ex.StackTrace); 
    /* additional code to stop bgWorker */ 

} 

にSQLから報告された「BackupDatabaseなどを」実行するために、クラスAのインスタンスを使用するのBackgroundWorkerを使用しています、私はそれに応じて、例外がそこからスローされるたびに、BackgroundWorker ClassA.BackupInfoMessagesからスローされた例外をキャッチしていません...私はtry/catchブロックの周りを移動し、BackupDatabaseメソッドで幸運と1つを追加しようとしました。それはちょうどそれをスキップし、例外がスローされていないかのように扱うようです。 VSのデバッガは、System.Exceptionがスローされたが、何も影響を受けていないことを示しています。何かを逃したり、何か間違っているのですか?ありがとう!

+0

私はExecuteNonQuery()に切り替えました。助けてくれてありがとう! – ephtee

+1

私は自分の答えを削除しました。これは、呼び出し元のコードが本当に例外を捕らえたはずであることを見ています。それはあなたがVSでそれを見ているが、それは呼び出しメソッドで捕らえられていない奇妙です...それを直面する必要があります: - | – Clay

+0

バックグラウンドワーカーで例外をキャッチしないで、ワーカのRunWorkerCompletedイベントで例外を処理することを試してみることもあります。演奏中に複数のスレッドがある場合、これをキャッチするより適切な方法かもしれません。 – Clay

答えて

1

BackupInfoMessagesは自分の別のバックグラウンドワーカーで実行していると考える必要があります。その理由は、イベントがtry/catchブロックと同じ呼び出しスタックにないためです。

エラーが発生したことを伝えるために、直接例外を発生させる以外の方法が必要です。

エラーレベルが11以上であれば、ExecuteNonQueryは例外情報をエラー情報とともにスローしますので、イベントハンドラ内で手動で例外を発生させる必要はありません。ただし、.FireInfoMessageEventOnUserErrors = trueを設定すると、その動作が変更されることがあります。

+0

私は頭の上からエラー情報を表示するための良い代替方法を知らないが、もし私が1つ考えるならば、答えを例で更新するだろう。 –

+0

'.FireInfoMessageEventOnuserErrors'をfalseに設定する(または削除する)と、例外がスローされ、私の問題が部分的に解決されます。一方、SQLからInfoMessagesを送信することなく、バックアップの進行状況をユーザーに報告する方法はありません。 – ephtee

+0

私は単純にプロセスが失敗し、SQLメッセージの重大度に対してテストし、それに応じてブール値を変更したかどうかを確認するために公開ブール値を割り当て、クエリが完了した後にブール値をテストし、結果によってBackupDatabase 。 – ephtee

関連する問題