捕捉using语句内的异常,应该把try-catch写在using内还是外?

啊宝儿姐 2019-02-19 11:06:40
通常,using语句会在结束时执行Dispose(),进行垃圾回收(GC),针对于这一点,当我们想捕捉using语句内的异常时,应该把try-catch写在using内还是外?
这里有两个假设,
第一,我们正确处理了异常;
第二,我们未能正确处理异常,即程序抛错了。
...全文
2585 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
half_bucket 2019-02-21
  • 打赏
  • 举报
回复
引用 28 楼 以专业开发人员为伍 的回复:
这是一个正常的程序设计过程中遇到的问题,这里强调的是“只做必要的事情”,强调从需求和逻辑出发而不是“为了技术而技术”的用其它问题耽误时间。那么怎么回去纠结无关的“要在别人编译完的dll里编写什么代码”的问题?

实际上理解问题的出发点,能深如一点到程序开发设计的理念。如果不能理解为什么会“太技术化”,反而陷入了更多争论。


从成熟的开发思维出发,理解using这段代码的运行逻辑,如何写就顺理成章了。
  • 打赏
  • 举报
回复
这是一个正常的程序设计过程中遇到的问题,这里强调的是“只做必要的事情”,强调从需求和逻辑出发而不是“为了技术而技术”的用其它问题耽误时间。那么怎么回去纠结无关的“要在别人编译完的dll里编写什么代码”的问题? 实际上理解问题的出发点,能深如一点到程序开发设计的理念。如果不能理解为什么会“太技术化”,反而陷入了更多争论。
luj_1768 2019-02-21
  • 打赏
  • 举报
回复
说实话,如果代码被声明为dll ,原则上讲是拒绝调试的。using 引用的代码库可能也是这样的。能否讲讲遇到的问题,也许大家能想出个答案来。这个题目,废了,无解。
burt120 2019-02-21
  • 打赏
  • 举报
回复
来学习 来学习
threenewbee 2019-02-20
  • 打赏
  • 举报
回复
引用 9 楼 圣殿骑士18 的回复:
放哪里都可以,无所谓,using本身也是try catch。我建议是放using里边。这样代码好看!

==========
欢迎关注微信公众号 “产品技术知与行” ,打造全面的结构化知识库,包括原创文章、免费课程(C#,Java,Js)、技术专题、视野知识、源码下载等内容。
最新文章:多种Timer的场景应用 https://mp.weixin.qq.com/s/TJKi7PBj3nznf9FClirXUA


正解
using就是try...finally
wangjinggang999 2019-02-20
  • 打赏
  • 举报
回复
学习了,谢谢
卖水果的net 2019-02-20
  • 打赏
  • 举报
回复
using 只会执行一个 Dispose,别的代码加不进去。 try catch 程序员自由发挥的空间很大。 以上,我是听我们程序员说的,不知道对楼来说有没有参考价值。
  • 打赏
  • 举报
回复
有些伪命题是说“我就是要捕捉using语句‘内’的异常,应该把try-catch写在using内还是外?”,这类伪命题是太技术化了,所以是伪命题。我要告诉你的就是:不要太技术化。技术是次要的!
zywplc 2019-02-20
  • 打赏
  • 举报
回复
学习中,谢谢
wanghui0380 2019-02-19
  • 打赏
  • 举报
回复
至于你说要捕捉里面的,我们说还是看上下文。
你确定try外面的一定没错么?
你并不确定,代码会在那里异常,一个小小的 new byte[] x=new byte[filesteam.length]都会异常,那么你觉着那里不会异常?

那么为了知道是哪里异常,自然是放在最外面。

ps:使用线程除外,线程处理异常要放在里面,因为线程里异常会让线程挂掉,而外面还没有异常消息。所以线程里面的东西,得放线程里面异常得放线程里面处理。所以我们说忽略上下文去单纯讨论那个好,那么不好,没什么价值
肉肉牛� 2019-02-19
  • 打赏
  • 举报
回复
在调用某函数时,如果使用了try catch语句捕获该函数产生的异常,而如果这个函数内调用了其它函数,其它函数又掉了另外的函数,如果
我不懂电脑 2019-02-19
  • 打赏
  • 举报
回复
最好写在要捕捉异常的位置,定位更准确
Chasmれ 2019-02-19
  • 打赏
  • 举报
回复
using (Class1 cls1 = new Class1(), cls2 = new Class1())
{
  // the code using cls1, cls2
} // call the Dispose on cls1 and cls2
当在某个代码段中使用了类的实例,而希望无论因为什么原因,只要离开了这个代码段就自动调用这个类实例的Dispose。 要达到这样的目的,用try...catch来捕捉异常也是可以的,但用using也很方便。
正怒月神 2019-02-19
  • 打赏
  • 举报
回复
怎么写都可以,但是最好使用全局异常来处理日志
wanghui0380 2019-02-19
  • 打赏
  • 举报
回复
无所谓,我们更关心你有没有finally

如果有finally,那么他有可能需要做手尾处理。并不一定是清理context,也许是干点别的事情,那么如果要用到try里面的变量,他就会迫不得已的写到try外面去。

所以我们并不纠结这种没有上下文的所谓“高级性能技巧”,这种技巧不值几个钱。我们更在乎上下文,在乎业务本身的最小化和正交性。你先给我保证“业务本身的最小化和正交性”,然后再来给我讨论“手割”技巧

ps:手割-围棋术语。研究局部手段顺序最优性--------但是前提是你能赢整盘棋,你要看到整盘棋而不是整天研究2,3步棋。手割是给盘后复盘,研究得失,总结经验用的,而不是给你下棋的时候玩的。
啊宝儿姐 2019-02-19
  • 打赏
  • 举报
回复
引用 18 楼 圣殿骑士18 的回复:
[quote=引用 2 楼 初出茅庐的孩子 的回复:] 2楼给出个人看法: a.如果我们能正确处理异常,这两种写法都能捕获异常。 b.如果不能正确处理异常,导致程序出错,则通过方法2,能在程序出错前,GC能回收我们的托管对象。 结论:没多大差别。如果程序都出错了,还管那么多干嘛。
你这观点是错的。方法1也能回收。两个方法都能回收,所以没差别。[/quote] 谢谢大佬指正
  • 打赏
  • 举报
回复
using是不管你包含的内部是否包含了异常,都能正确释放 所以两种写法没多大区别,实际按需要是放外面还是放里面 不过一般来说,个人还是建议不要try catch,让异常抛到上层,由展示层决定如何处理
啊宝儿姐 2019-02-19
  • 打赏
  • 举报
回复
2楼给出个人看法: a.如果我们能正确处理异常,这两种写法都能捕获异常。 b.如果不能正确处理异常,导致程序出错,则通过方法2,能在程序出错前,GC能回收我们的托管对象。 结论:没多大差别。如果程序都出错了,还管那么多干嘛。
啊宝儿姐 2019-02-19
  • 打赏
  • 举报
回复
1楼附测试代码:
class Program
    {
        static void Main(string[] args)
        {
            //方法1
            //using (var context = new TestClass())
            //{
            //    try
            //    {
            //        throw new Exception("eee");
            //    }
            //    catch (Exception e)
            //    {
            //        Console.WriteLine(e);
            //        //throw e;
            //    }
 
            //}
            //方法2
            try
            {
                using (var context = new TestClass())
                {
                    throw new Exception("eee");
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                //throw e;
            }
            Console.ReadLine();
        }
    }
    public class TestClass : System.IDisposable
    {
        //供程序员显式调用的Dispose方法
        public void Dispose()
        {
            Console.WriteLine("Run Dispose");
            //调用带参数的Dispose方法,释放托管和非托管资源
            Dispose(true);
            //手动调用了Dispose释放资源,那么析构函数就是不必要的了,这里阻止GC调用析构函数
            System.GC.SuppressFinalize(this);
        }
 
        //protected的Dispose方法,保证不会被外部调用。
        //传入bool值disposing以确定是否释放托管资源
        protected void Dispose(bool disposing)
        {
            Console.WriteLine("Run Dispose(" + disposing + ")");
            if (disposing)
            {
                ///TODO:在这里加入清理"托管资源"的代码,应该是xxx.Dispose();
            }
            ///TODO:在这里加入清理"非托管资源"的代码
        }
 
        //供GC调用的析构函数
        ~TestClass()
        {
            Console.WriteLine("Run ~TestClass");
            Dispose(false);//释放非托管资源
        }
    }
圣殿骑士18 2019-02-19
  • 打赏
  • 举报
回复
引用 2 楼 初出茅庐的孩子 的回复:
2楼给出个人看法:
a.如果我们能正确处理异常,这两种写法都能捕获异常。
b.如果不能正确处理异常,导致程序出错,则通过方法2,能在程序出错前,GC能回收我们的托管对象。
结论:没多大差别。如果程序都出错了,还管那么多干嘛。


你这观点是错的。方法1也能回收。两个方法都能回收,所以没差别。
加载更多回复(7)

110,571

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧