处理类库(dll)中的异常 [英] Handling exceptions in class library (dll)

查看:79
本文介绍了处理类库(dll)中的异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

哪种方法是处理C#类库中异常的最佳方法?
在我的dll中,我有类似这样的内容:

Which way is the best way for handling exceptions in C# class library ?
In my dll I have something like this :

public bool Rename(string newName)
        {
            if (!this._parameters.Database.Equals(this.Database.Name))
                this._parameters.SelectDatabase(this.Database.Name);
            try
            {
                if (string.IsNullOrEmpty(newName))
                    throw new ArgumentException("Invalid new table name (NULL or empty).");

                using (MySqlConnection connection = new MySqlConnection(this._parameters.ConnectionString))
                {
                    connection.Open();
                    using (MySqlCommand command = new MySqlCommand(Queries.Rename(this.Name, newName), connection))
                    {
                        command.ExecuteNonQuery();
                    }
                    connection.Close();
                }
                this.Name = newName;
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }



在我的应用程序中,我检查method的返回值.
如果是真的,则继续执行,否则显示带有一般错误消息的简单MessageBox.

现在,我想根据异常类型和消息向用户显示更精确的错误.

我可以这样做吗:



In my application, I check return value of method.
If it is true than it just continue with execution, otherwise it displays simple MessageBox with general error message.

Now I want to show more precise error to user, based on exception type and message.

May I do it like this :

public bool Rename(string newName,out Exception exception)
        {
            if (!this._parameters.Database.Equals(this.Database.Name))
                this._parameters.SelectDatabase(this.Database.Name);
            try
            {
                if (string.IsNullOrEmpty(newName))
                    throw new ArgumentException("Invalid new table name (NULL or empty).");

                using (MySqlConnection connection = new MySqlConnection(this._parameters.ConnectionString))
                {
                    connection.Open();
                    using (MySqlCommand command = new MySqlCommand(Queries.Rename(this.Name, newName), connection))
                    {
                        command.ExecuteNonQuery();
                    }
                    connection.Close();
                }
                this.Name = newName;
                return true;
            }
            catch (Exception exc)
            {
                exception = exc;
                return false;
            }
        }


然后,如果方法返回false,则会向用户显示正确的消息和提示.

有更好更好的方法吗?

在此先感谢


Nikola


and then if method returns false I show a proper message and hint to the user.

Any better and faster way ?

Thanks in advance


Nikola

推荐答案

对于例外,程序集之间没有边界.在堆栈上操作的异常,每个堆栈都属于一个线程.

请参阅其他答案.

这是一个经验法则:在大多数情况下,不要在库中捕获异常.您需要在每个线程的最高堆栈帧上捕获异常.

有一些例外情况:有时您需要捕获原始异常,创建更多语义异常,然后将其重新抛出.在极少数情况下,您可以完全阻止异常传播,因为您可以在运行时完全解决"该问题.一种这样的情况是用户输入错误,并且修复"将再次提示用户,直到问题解决.但是,这不是通常的方法,也不是最推荐的方法.完全阻止异常的另一种情况是使用某些有缺陷的代码,这些代码在其源代码形式的补丁中不可用.

UI有它自己的异常处理策略:在面向事件的主循环中捕获所有异常.我用我过去的答案之一解释它.请参阅:

我如何制作滚动条到达底部时将停止的循环 [当我运行应用程序时,例外是捕获了如何处理此问题? [扔. .then ... rethrowing [ ^ ].

—SA
For exceptions, there are no boundaries between assemblies. An exception operated on a stack, and each stack belongs to a thread.

Please see other answers.

Here is a rule of thumb: in most cases, don''t catch exceptions in libraries. You need to catch exceptions on a very top stack frame of each thread.

There are exclusions: sometime you need to catch a raw exception, create a more semantic exception and re-throw it. In rare cases you can block exception propagation completely, as you can fully "fix" the problem during run-time. One such case is wrong user input, and the "fix" would be prompting the user again until the problem is resolved. However, this is not the usual and not the most recommended way. Another case of total blocking of the exception is working with some defected code which is not available in its source form for a patch.

UI has it''s own exception handling strategy: catching all exception in the main event-oriented loop. I explain it in one of my past answers. Please see:

How do i make a loop that will stop when a scrollbar reaches the bottom[^],
When i run an application an exception is caught how to handle this?[^],
throw . .then ... rethrowing[^].

—SA


如果要在调用代码中添加异常,则实际上应该抛出该异常.也就是说,请尝试使用该方法.

如果您只想显示一条错误消息,则最好是执行"out string errorMessage"而不是异常.
If you want the exception in the calling code, you should really just throw the exception. i.e. take the try catch out of the method.

If you just want an error message, then you''re probably better doing ''out string errorMessage'' instead of the exception.


我个人希望尽可能晚地处理异常.例如,如果我是你,我将在要向用户显示消息的确切位置处处理异常.

但是问题是,您不能从核心类到GUI级别抛出所有异常.您将必须编写一百万个catch块.基本上是丑陋的.您可以做的是通过将异常包装在自己的异常中来软化异常.这样,可以将异常重新抛出到尽可能远的位置,但以一种可管理的方式.

实际上,这既是设计又是编程技术.
I personally like to handle exceptions as late as possible. For example if I were you, I will handle the exception at exact point where I want to show the message to user.

But the problem is, you can''t throw up all the exception from core classes to the GUI level. You will have to write a million catch blocks. It is basically ugly. What you can do is soften up the exception by wrapping them in your own exceptions. This way, exception is re-thrown back as farther as possible, but in a manageable way.

Actually this is a design thing as well as a programming technique.


这篇关于处理类库(dll)中的异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆