Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 正在捕获线程中的系统异常_C#_.net_Exception_Exception Handling - Fatal编程技术网

C# 正在捕获线程中的系统异常

C# 正在捕获线程中的系统异常,c#,.net,exception,exception-handling,C#,.net,Exception,Exception Handling,我知道捕捉System.Exception不是一个好的做法,除非是在应用程序的顶层。一根线怎么样?可以在线程的顶层捕获System.Exception吗 更新: 该线程是一个长时间运行的线程,只有在应用程序停止时才应该终止。因此,为了确保应用程序不会崩溃,我只需捕获System.Exception并记录错误。一切都被重新创造 while (Terminate == false) { var discoveryClient = new Dis

我知道捕捉System.Exception不是一个好的做法,除非是在应用程序的顶层。一根线怎么样?可以在线程的顶层捕获System.Exception吗

更新: 该线程是一个长时间运行的线程,只有在应用程序停止时才应该终止。因此,为了确保应用程序不会崩溃,我只需捕获System.Exception并记录错误。一切都被重新创造

        while (Terminate == false)
        {
            var discoveryClient = new DiscoveryClient(new UdpDiscoveryEndpoint());

            try
            {
                var criteria = new FindCriteria(typeof(T));
                criteria.Scopes.Add(new Uri(Scope));
                var discovered = discoveryClient.Find(criteria);
                discoveryClient.Close();
                discoveryClient = null;

                // do something with the endpoints
            }
            catch (OutOfMemoryException e)
            {
                m_Logger.LogException(e, "Exception when trying to discover clients (Contract: {0})", typeof(T).Name);
                throw;
            }
            catch (Exception e)
            {
                m_Logger.LogException(e, "Exception when trying to discover clients (Contract: {0})", typeof(T).Name);

                if (discoveryClient != null)
                    (discoveryClient as IDisposable).Dispose();
            }

        }

是的,这是个好主意:)

嗯,我不明白为什么人们认为捕捉顶级异常不是一个好主意。说真的,你抓不到他们


从实际的日常开发角度来看,如果您的后台线程有顶级异常,那么您希望了解它。你不希望应用程序崩溃,这是默认行为——令人惊讶的是,用户不喜欢这样。这是少数几个您肯定希望捕获异常并记录/恢复的地方之一。

这取决于线程正在做什么以及应用程序中线程的上下文。一般来说,您应该遵循黄金经验法则:除非您知道如何处理异常,否则不要捕获异常。(我当然在简化,但这是经验法则)

因为我们讨论的是
System.Exception
,而不是某个子类,所以我假设您实际上不知道如何处理异常。记录错误并让应用程序终止(捕获无法处理的异常的唯一合法原因),而不从引发异常的线程中捕获异常,因此简短的回答是不,不确定

如果我没记错的话.NET1实际上捕获并吞并了在后台线程上引发的所有异常。这导致写得不好的程序出现了很多问题,微软改变了.NET 2中的行为,让异常导致应用程序崩溃——你可以想象,他们有很好的理由做出这样一个突破性的改变

关于
后台工作人员的更新

请不要将
BackgroundWorker
的使用模式误认为是“吞咽
系统。异常情况
正常”。以下是文档的内容:

您的RunWorkerCompleted事件处理程序 应该经常检查 AsyncCompletedEventArgs.Error和 AsyncCompletedEventArgs。已取消 属性,然后再访问 RunWorkerCompletedEventArgs.Result 财产。如果引发了异常 或者如果手术被取消了, 访问 RunWorkerCompletedEventArgs.Result 属性引发异常

简单地说,选择忽略此建议或故意忽略返回值(否则仍将引发异常!)是一种糟糕的编程实践。

我们通常不打算直接创建新线程。只有在少数情况下才是可以接受的。 因此,如果您确实使用
new-Thread()
,尤其是在UI中,这将是不受欢迎的

我们鼓励使用
BackgroundWorker
Task
来封装线程异常处理,这样就不需要对
catch
块进行异常处理


这4种情况是可以接受的,您需要自己的线程(来自):

我强烈建议您使用 要执行异步的线程池 无论何时计算绑定操作 可能的然而,有一些 你可能想要的场合 显式创建一个专用线程 执行某一特定任务 计算绑定操作。典型的 您可能希望创建一个专用的 线程,如果您要执行代码 这要求线程处于 不正常的特定状态 对于线程池线程。例如 我会创建一个专用线程,如果我 希望线程以特殊的速度运行 优先级(所有线程池线程都运行 以正常优先级,您不应该 改变线程池线程的 优先权)。我也会考虑 创建和使用我自己的线程,如果我 想让这条线成为前景 线程(所有线程池线程都是 背景线程),因此 防止应用程序死亡 直到我的线程完成其 任务我也会使用专用线程 如果计算绑定任务 极长的运行时间;这边,我 不会让线程池的 它试图弄明白的逻辑 是否创建一个附加的 线最后,我会使用专用的 线程如果我想开始一个线程 并可能通过 调用线程的中止方法 (在第21章“CLR托管”中讨论) 和AppDomains”)


从官方的角度来看,这不是一个好的做法,但有时是这样的

参数与在“主”线程上执行此操作的参数完全相同

一个主要的问题是,如果您接受了这样的错误,那么您的应用程序可能会非常不正确地运行—例如,它可能会覆盖重要的用户数据—而不是终止



如果您确实选择了这条路线,您可能需要小心从捕获中排除
ThreadAbortException
——如果有人中止工作线程(在您的应用程序中可能是这样,也可能不是这样),这是一个“预期的异常”

仅处理您可以处理的异常。为了不显示黄色屏幕,我个人更喜欢在global.asax事件应用程序中捕获未损坏的异常\u error

在应用程序的顶层捕获
系统异常也不是一个好的做法()。你为什么要这么做?-1:这太过分了。当然,当线程是最合适的选项时,我们应该直接使用它。
我强烈建议您使用线程池。因此,请使用线程池(由
Task
BackgroundWorker
使用),而不是创建自己的线程。@Aliostad:new thread
ThreadPool.QueueUserWorkItem之间在概念上有什么区别吗