jjzjj

c# - 在展开嵌套的 "Dispose"语句时处理 "using"抛出的异常

coder 2024-05-29 原文

显然,在使用嵌套的 using 语句时,一些异常可能会丢失。考虑这个简单的控制台应用程序:

using System;

namespace ConsoleApplication
{
    public class Throwing: IDisposable
    {
        int n;

        public Throwing(int n)
        {
            this.n = n;
        }

        public void Dispose()
        {
            var e = new ApplicationException(String.Format("Throwing({0})", this.n));
            Console.WriteLine("Throw: {0}", e.Message);
            throw e;
        }
    }

    class Program
    {
        static void DoWork()
        {
            // ... 
            using (var a = new Throwing(1))
            {
                // ... 
                using (var b = new Throwing(2))
                {
                    // ... 
                    using (var c = new Throwing(3))
                    {
                        // ... 
                    }
                }
            }
        }

        static void Main(string[] args)
        {
            AppDomain.CurrentDomain.UnhandledException += (sender, e) =>
            {
                // this doesn't get called
                Console.WriteLine("UnhandledException:", e.ExceptionObject.ToString());
            };

            try
            {
                DoWork();
            }
            catch (Exception e)
            {
                // this handles Throwing(1) only
                Console.WriteLine("Handle: {0}", e.Message);
            }

            Console.ReadLine();
        }
    }
}

Throwing 的每个实例在被处理时都会抛出。 AppDomain.CurrentDomain.UnhandledException 永远不会被调用。

输出:

Throw: Throwing(3)
Throw: Throwing(2)
Throw: Throwing(1)
Handle: Throwing(1)

我希望至少能够记录丢失的 Throwing(2)Throwing(3)我该怎么做,而不是为每个 using 求助于单独的 try/catch(这会破坏 using 的便利性)?

在现实生活中,这些对象通常是我无法控制的类的实例。他们可能会或可能不会抛出,但如果他们这样做,我希望有一个选项来观察此类异常。

这个问题是在我查看 reducing the level of nested using 时出现的.有一个 neat answer建议聚合异常。有趣的是,这与嵌套 using 语句的标准行为有何不同。

[EDITED] 这个问题似乎密切相关: Should you implement IDisposable.Dispose() so that it never throws?

最佳答案

代码分析器对此有警告。 CA1065 ,“不要在意想不到的地方引发异常”。 Dispose() 方法在该列表中。在 Framework Design Guide 第 9.4.1 章中还有一个强烈警告:

AVOID throwing an exception from within Dispose(bool) except under critical situations where the containing process has been corrupted (leaks, inconsistent shared state, etc.).

这是错误的,因为 using 语句在 finally block 中调用了 Dispose()。在 finally block 中引发的异常可能会产生令人不快的副作用,如果在堆栈因异常而展开时调用 finally block ,它会替换一个事件异常。正是您在这里看到的情况。

重现代码:

class Program {
    static void Main(string[] args) {
        try {
            try {
                throw new Exception("You won't see this");
            }
            finally {
                throw new Exception("You'll see this");
            }
        }
        catch (Exception ex) {
            Console.WriteLine(ex.Message);
        }
        Console.ReadLine();
    }
}

关于c# - 在展开嵌套的 "Dispose"语句时处理 "using"抛出的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19238521/

有关c# - 在展开嵌套的 "Dispose"语句时处理 "using"抛出的异常的更多相关文章

  1. ruby-on-rails - rails : "missing partial" when calling 'render' in RSpec test - 2

    我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou

  2. ruby-on-rails - 由于 "wkhtmltopdf",PDFKIT 显然无法正常工作 - 2

    我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-

  3. ruby-on-rails - Rails 编辑表单不显示嵌套项 - 2

    我得到了一个包含嵌套链接的表单。编辑时链接字段为空的问题。这是我的表格:Editingkategori{:action=>'update',:id=>@konkurrancer.id})do|f|%>'Trackingurl',:style=>'width:500;'%>'Editkonkurrence'%>|我的konkurrencer模型:has_one:link我的链接模型:classLink我的konkurrancer编辑操作:defedit@konkurrancer=Konkurrancer.find(params[:id])@konkurrancer.link_attrib

  4. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  5. ruby - 将散列转换为嵌套散列 - 2

    这道题是thisquestion的逆题.给定一个散列,每个键都有一个数组,例如{[:a,:b,:c]=>1,[:a,:b,:d]=>2,[:a,:e]=>3,[:f]=>4,}将其转换为嵌套哈希的最佳方法是什么{:a=>{:b=>{:c=>1,:d=>2},:e=>3,},:f=>4,} 最佳答案 这是一个迭代的解决方案,递归的解决方案留给读者作为练习:defconvert(h={})ret={}h.eachdo|k,v|node=retk[0..-2].each{|x|node[x]||={};node=node[x]}node[

  6. ruby - 检查 "command"的输出应该包含 NilClass 的意外崩溃 - 2

    为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar

  7. ruby-on-rails - Rails 应用程序中的 Rails : How are you using application_controller. rb 是新手吗? - 2

    刚入门rails,开始慢慢理解。有人可以解释或给我一些关于在application_controller中编码的好处或时间和原因的想法吗?有哪些用例。您如何为Rails应用程序使用应用程序Controller?我不想在那里放太多代码,因为据我了解,每个请求都会调用此Controller。这是真的? 最佳答案 ApplicationController实际上是您应用程序中的每个其他Controller都将从中继承的类(尽管这不是强制性的)。我同意不要用太多代码弄乱它并保持干净整洁的态度,尽管在某些情况下ApplicationContr

  8. ruby-on-rails - 迷你测试错误 : "NameError: uninitialized constant" - 2

    我遵循MichaelHartl的“RubyonRails教程:学习Web开发”,并创建了检查用户名和电子邮件长度有效性的测试(名称最多50个字符,电子邮件最多255个字符)。test/helpers/application_helper_test.rb的内容是:require'test_helper'classApplicationHelperTest在运行bundleexecraketest时,所有测试都通过了,但我看到以下消息在最后被标记为错误:ERROR["test_full_title_helper",ApplicationHelperTest,1.820016791]test

  9. ruby-on-rails - Rails - 乐观锁定总是触发 StaleObjectError 异常 - 2

    我正在学习Rails,并阅读了关于乐观锁的内容。我已将类型为integer的lock_version列添加到我的articles表中。但现在每当我第一次尝试更新记录时,我都会收到StaleObjectError异常。这是我的迁移:classAddLockVersionToArticle当我尝试通过Rails控制台更新文章时:article=Article.first=>#我这样做:article.title="newtitle"article.save我明白了:(0.3ms)begintransaction(0.3ms)UPDATE"articles"SET"title"='dwdwd

  10. ruby-on-rails - 相关表上的范围为 "WHERE ... LIKE" - 2

    我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que

随机推荐