Throwing multiple exceptions in .Net/C#

前端 未结 5 1426
渐次进展
渐次进展 2020-12-15 15:22

In an application I work on, any business logic error causes an exception to be thrown, and the calling code handles the exception. This pattern is used throughout the appl

相关标签:
5条回答
  • 2020-12-15 16:05

    No super-elegant solution here but a few ideas:

    • Pass an error-handler function as argument to DoTasks so the user can decide whether to continue
    • Use tracing to log errors as they occur
    • Concatenate the messages from the other exceptions in the exception bundle's message
    0 讨论(0)
  • 2020-12-15 16:06

    The Task Parallel Library extensions for .NET (which will become part of .NET 4.0) follow the pattern suggested in other answers: collecting all exceptions that have been thrown into an AggregateException class.

    By always throwing the same type (whether there is one exception from the child work, or many), the calling code that handles the exception is easier to write.

    In the .NET 4.0 CTP, AggregateException has a public constructor (that takes IEnumerable<Exception>); it may be a good choice for your application.

    If you're targeting .NET 3.5, consider cloning the parts of the System.Threading.AggregateException class that you need in your own code, e.g., some of the constructors and the InnerExceptions property. (You can place your clone in the System.Threading namespace inside your assembly, which could cause confusion if you exposed it publicly, but will make upgrading to 4.0 easier later on.) When .NET 4.0 is released, you should be able to “upgrade” to the Framework type by deleting the source file containing your clone from your project, changing the project to target the new framework version, and rebuilding. Of course, if you do this, you need to carefully track changes to this class as Microsoft releases new CTPs, so that your code doesn't become incompatible. (For example, this seems like a useful general-purpose class, and they could move it from System.Threading to System.) In the worst case, you can just rename the type and move it back into your own namespace (this is very easy with most refactoring tools).

    0 讨论(0)
  • 2020-12-15 16:13

    You could create a custom Exception that itself has a collection of Exceptions. Then, in your Catch block, just add it to that collection. At the end of your process, check if the Exception count is > 0, then throw your custom Exception.

    0 讨论(0)
  • 2020-12-15 16:19

    Two ways of the top of my head would be either make a custom exception and add the exceptions to this class and throw that the end :

    public class TaskExceptionList : Exception
    {
        public List<Exception> TaskExceptions { get; set; }
        public TaskExceptionList()
        {
            TaskExceptions = new List<Exception>();
        }
    }
    
        public void DoTasks(MyTask[] taskList)
        {
            TaskExceptionList log = new TaskExceptionList();
            foreach (MyTask task in taskList)
            {
                try
                {
                    DoTask(task);
                }
                catch (Exception ex)
                {
                    log.TaskExceptions.Add(ex);
                }
            }
    
            if (log.TaskExceptions.Count > 0)
            {
                throw log;
            }
        }
    

    or return true or false if the tasks failed and have a 'out List' variable.

        public bool TryDoTasks(MyTask[] taskList, out List<Exception> exceptions)
        {
            exceptions = new List<Exception>();
            foreach (MyTask task in taskList)
            {
                try
                {
                    DoTask(task);
                }
                catch (Exception ex)
                {
                    exceptions.Add(ex);
                }
            }
    
            if (exceptions.Count > 0)
            {
                return false;
            }
            else
            {
                exceptions = null;
                return true;
            }
        }
    
    0 讨论(0)
  • 2020-12-15 16:19

    You might want to use a BackgroundWorker to do this for you. It automatically captures and presents any exceptions when completed, which you could then throw or log or do whatever with. Also, you get the benefit of multithreading.

    The BackgroundWorker is a nice wrapper around delegate's asynchronous programming model.

    0 讨论(0)
提交回复
热议问题