6

コードでThrowをどのように使用するかを理解しようとしています。WindowsフォームGUIを処理するためのMainFormクラスがあり、次にファイルとの間でデータを読み書きするためのManagerクラスがあります。

私は両方のクラスでTry/Catchを使用していますが、インストラクターはManagerクラスでThrowを使用することを望んでいます。それについて読んでいるにもかかわらず、それが何をするのかわかりません。ThrowはMainFormクラスのTry/Catchに影響しますか?

例外がキャッチされた場合もマネージャークラスでメッセージボックスを使用しますが、インストラクターによると、マネージャーにメッセージボックスを含めることはできません。どうすればよいですか?MainFormクラスでのみメッセージボックスを使用できますか?私の知識を理解し、拡大するためのいくつかの助けを正確に!ありがとう!

MainFormクラス:

try
{
     motelManager.SaveToFile(file);
}
catch
{
     MessageBox.Show("Ett fel uppstod!", "Varning!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}

マネージャークラス:

 public void SaveToFile(string filePath)
 {
     try
     {
         string newFilePath = filePath.Replace(".bin", "");
         filestream = new FileStream(newFilePath + ".bin", FileMode.Create);
         BinaryFormatter b = new BinaryFormatter();
         b.Serialize(filestream, animals);
     }
     catch(Exception ex)
     {
         MessageBox.Show(ex.Message, "Varning!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
     }

     if (filestream != null) filestream.Close();
 }
4

7 に答える 7

6

your manager class should look like this:

public void SaveToFile(string filePath)
{
    try
    {
        string newFilePath = filePath.Replace(".bin", "");
        filestream = new FileStream(newFilePath + ".bin", FileMode.Create);
        BinaryFormatter b = new BinaryFormatter();
        b.Serialize(filestream, animals);
    }
    catch(Exception ex)
    {
        if (filestream != null) filestream.Close();
        throw;
        // but don't use
        // throw ex;
        // it throws everything same
        // except for the stacktrace
    }
    // or do it like this
    //catch(Exception ex)
    //{
    //    throw;
        // but don't use
        // throw ex;
        // it throws everything same
        // except for the stacktrace
    //}
    //finally
    //{
    //    if (filestream != null) filestream.Close();
    //}

}

and in your main class:

try
{
    motelManager.SaveToFile(file);
}
catch (Exception e)
{
    MessageBox.Show("Ett fel uppstod!", "Varning!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
于 2012-07-30T09:35:25.917 に答える
1
public void SaveToFile(string filePath)
{
    try
    {
         string newFilePath = filePath.Replace(".bin", "");
         filestream = new FileStream(newFilePath + ".bin", FileMode.Create);
         BinaryFormatter b = new BinaryFormatter();
         b.Serialize(filestream, animals);
    }
    catch (Exception ex)
    {
        if (filestream != null) filestream.Close();
        //what you want
        //MessageBox.Show(ex.Message, "Warning!");
        throw (new Exception("Your custom message"));
    }
}

And in your manager:

try
{
    manager.SaveToFile(filePath);
}
catch (Exception ex)
{
    // here shows your 'Your custom message'
    MessageBox.Show(ex.Message);
}
于 2012-07-30T09:35:23.147 に答える
1

you can use Application ThreadException to catch any exception. And your save logic to wrap with using instead of try catch, in this case it will close your stream.

public void SaveToFile(string filePath)
{
    string newFilePath = filePath.Replace(".bin", "");
    using(var filestream = new FileStream(newFilePath + ".bin", FileMode.Create))
    {
        BinaryFormatter b = new BinaryFormatter();
        b.Serialize(filestream, animals);
    }
}

in the entry point (static void main()) subscribe to this event.

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());

        Application.ThreadException += Application_ThreadException;
    }

    static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
    {
        MessageBox.Show(".......");
    }
于 2012-07-30T09:35:33.490 に答える
1

Throwは、呼び出し元の関数の例外を発生させるだけです。(この場合、SaveToFileを呼び出す人)。そこにエラーハンドラがある場合はキャッチされます。それ以外の場合は、キャッチされるかトップレベルになるまでコールスタックを継続します。

于 2012-07-30T09:39:27.653 に答える
1

フォームでのユーザーへの表示という観点から例外を処理することをお勧めします。これは、より大規模で適切に構造化されたシステムでは、ManagerオブジェクトがGUIに接続していない可能性があるためです。

一般的なルールは、バックエンド[Manager]クラスで例外をキャッチして、リソースをクリーンアップ(つまり、ファイルを閉じる)してから、次のように例外ハンドラーから例外を再スローすることです。

public void SaveToFile(string filePath)
{
    try
    {
        string newFilePath = filePath.Replace(".bin", "");
        filestream = new FileStream(newFilePath + ".bin", FileMode.Create);
        BinaryFormatter b = new BinaryFormatter();
        b.Serialize(filestream, animals);
    }
    catch(Exception ex)
    {
        /* 
         * cleanup resources and rethrow the exception for catching and handling elsewhere
         */
        if (filestream != null)
            filestream.Close();
        throw;
    }

}
于 2012-07-30T09:39:33.540 に答える
1

複数の層を持つアプリケーションでは、基になる層で発生する例外は、上位層または呼び出し元のアプリケーションにそのまま送信されません。

たとえば、データベース関連のコードで問題が発生した場合、それをクライアントアプリケーションまたは上位層に送信しません。そうする理由は、ユーザーにわかりやすいエラーメッセージを提供するためです。たとえば、削除操作中に外部キー参照エラーが発生した場合、次のことができます。

  1. 例外情報をログに記録します。
  2. ユーザーフレンドリーな例外メッセージに置き換えて、上のレイヤーにスローします。

上記のレイヤーは、この例外を別のより高いレベルのメッセージにラップしてから、先にスローする場合があります。これはあなたがするように頼まれたことに似ています。

Managerクラスのコードで、発生する可能性のある例外の数を確認します。VSを使用している場合は、ツールチップ/ヘルプテキストにその情報が記載されています。VSを使用していない場合は、MSDNでこの情報を確認してください。

フォームでは、マネージャーレイヤーによってスローされる可能性のあるすべての例外と、何かひどく間違ったことが発生した場合の一般的な例外を処理します。私見、これはマネージャー層のコードがどのようになるべきかです

try
            {
                string newFilePath = filePath.Replace(".bin", "");
                FileStream filestream = new FileStream(newFilePath + ".bin", FileMode.Create);
                BinaryFormatter b = new BinaryFormatter();
                b.Serialize(filestream, animals);
            }
            catch (ArgumentNullException argNullException)
            {
                // Log current exception

                // Wrap it under your exception type
                CustomWrapException customWrap = new CustomWrapException();
                customWrap.Message = "Your custom message here.";
                customWrap.InnerException = argNullException;
                throw customWrap;
            }
            catch (SecurityException securityException)
            {
                // Log current exception

                // Replace current exception with you custom exception
                CustomReplaceException replaceException = new CustomReplaceException();
                replaceException.Message = "Your custom message here.";
                throw replaceException;
            }
            finally
            {
                // Close stream and dispose objects here
            }

フォームには、次のような例外処理が必要です。

try
            {
                // Call mananger code from here
            }
            catch (CustomWrapException wrapException)
            {
                // replace/wrap if desired
                // Display message to user
            }
            catch (CustomReplaceException replaceException)
            {
                // replace/wrap if desired
                // Display message to user
            }
            catch (Exception exception)
            {
                // This is for everything else that may go wrong apart from known possible exceptions
                // Display message to user
            }
            finally
            {

            }

HTH。

于 2012-07-30T09:51:33.553 に答える
0

こんな感じ…

 try { } 
catch(Exception e) 
{ throw } 

例外をスローすると、ソースとスタックトレースが変更されるため、このメソッドから例外がスローされたように見えます。その行から、そのtry-catchブロックを含むメソッドにeがスローされます。

于 2012-07-30T09:38:10.013 に答える