尝试抓住投掷

时间:2012-07-30 09:29:26

标签: c# .net

我试图了解我将如何在我的代码中使用Throw。我有一个MainForm类来处理Windows窗体GUI,然后我有Manager类来读取和保存文件中的数据。

我在两个课程中都使用了Try / Catch,但是我的教练希望我在Manager课程中使用Throw,尽管我正在阅读它,但我不明白它会做什么? Will Throw会影响MainForm类中的Try / Catch吗?

如果捕获了异常,我还在manager类中使用了一个消息框,但是根据教师的说法,不允许在管理器中使用消息框,那么我该怎么办呢?我可以只在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();
 }

7 个答案:

答案 0 :(得分:6)

你的经理班应该是这样的:

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();
    //}

}

并在您的主要班级中:

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

答案 1 :(得分: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"));
    }
}

在你的经理中:

try
{
    manager.SaveToFile(filePath);
}
catch (Exception ex)
{
    // here shows your 'Your custom message'
    MessageBox.Show(ex.Message);
}

答案 2 :(得分:1)

您可以使用Application ThreadException来捕获任何异常。而且你的保存逻辑包括使用而不是try catch,在这种情况下它会关闭你的流。

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);
    }
}

在入口点(static void main())订阅此事件。

    [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(".......");
    }

答案 3 :(得分:1)

抛出只会将异常引发到调用函数。 (在这种情况下,无论谁调用SaveToFile)。如果那里有一个错误处理程序,它将被捕获,否则它将继续向上调用堆栈,直到它被捕获或处于顶层。

答案 4 :(得分: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;
    }

}

答案 5 :(得分:1)

在具有多个层的应用程序中,基础层中发生的异常不会发送到更高层或调用应用程序。

例如,如果数据库相关代码出现问题,则不会将其发送到客户端应用程序或更高层。这样做的原因是为用户提供友好的错误消息。比如,在删除操作期间您有外键引用错误,您可以:

  1. 记录异常信息。
  2. 替换为用户友好的异常消息并将其扔到上面的图层。
  3. 上面的层可能会将此异常包装到另一个更高级别的消息,然后将其抛出。这类似于你被要求做的事情。

    在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。

答案 6 :(得分:0)

就像这样......

 try { } 
catch(Exception e) 
{ throw } 

当它抛出异常时,它将改变源和堆栈跟踪,以便从包含该try-catch块的方法的那一行抛出e看起来已经从该方法抛出异常。