• 将不确定变为确定~程序是否真的Dispose了


    回到目录

    首先将来说一下Dispose是什么东西吧,对于我们使用非托管的资源时,需要自己去实现Dispose这个方法,它的含义就是释放使用的内存空间。

    例如Stream这个类型,它就是一个非托管类型,它会实现一个IDisposable接口,来实现Dispose方法

    image

    像TransactionScope,.net事务,它也是一个非托管的,也就是说,我们在使用完事务后,需要自己去进行Dispose()操作,下面问题就来了,这个Dispose写在哪里合适呢?

    注意看这段代码:

    using (TransactionScope trans = new TransactionScope())
             {
                 try
                 {
                     this.Update(order);
                     new WebAccountRecordsRepository().Insert(new WebAccountRecords
                     {
                         
                     });
                     new WebAccountBalancesRepository().Update(new WebAccountBalances { });
                 }
                 catch (Exception e)
                 {
                    // vm.AddItem(e.Message);
                     throw;
                 }
                 finally
                 {
                     trans.Dispose(); 
                 }
             }

    这是非常标准的写到,完成一个订单处理的过程,它将处理订单,网站支付明细及网站总余额写在了一个事务里,这当然是没有问题的,注意看Dispose的位置,写在了finally{}里,这也是对的,当try{}完成后,将会执行finally片断,但注意catch{}段,它进行所有异常的捕捉,并进行抛出,好了,如果这个try{}段出现了异常,那finally{}段是否会执行吗?也就是dispose是否会被执行呢?

    经过我的测试,它有执行,但由于你使用了throw,所以网页直接黄屏了,所以,最好把catch段进行处理,你可以去把异常写到日志里,但有一点要注意,finally{}块里不要写可能会出现异常的代码,否则,会使你的事务资源永远得到不释放!

    例如:

    using (TransactionScope trans = new TransactionScope())
           {
               try
               {
                   this.Update(order);
                   new WebAccountRecordsRepository().Insert(new WebAccountRecords
                   {
                       
                   });
                   new WebAccountBalancesRepository().Update(new WebAccountBalances { });
               }
               catch (Exception e)
               {
                  // vm.AddItem(e.Message);
                   throw;
               }
               finally
               {
                   Insert(list.First().id); //如果list集合为空,那这行会出现异常,导致它下面的代码将不能被执行
                   trans.Dispose(); 
               }
           }

    当然,这一般是由于编程习惯引起的,大家以后注意就行了,在finally里释放资源时,应该考虑异常进行一些必要的判断。

    如果非要写在finally里,如果你的对象不能确定是否会发生异常,那就try,catch吧,看代码:

    finally

      {

           try {

                Insert(list.First().id); //如果list集合为空,那这行会出现异常,导致它下面的代码将不能被执行

               }

              catch (Exception e)

              {

                throw;

              }

             finally

              {

                trans.Dispose();

              }

    }

    这样,trans.Dispose()也是会被执行的,也就是说,对于同一个try,catch,finally来说,finally是永远都会被执行的。

    回到目录

  • 相关阅读:
    Linux 安装中文man手册
    centos6.9使用NTFS-3G挂载ntfs文件系统
    Linux基础知识之挂载详解(mount,umount及开机自动挂载)
    技术点总结
    SQL 分组后获取其中一个字段最大值的整条记录 【转载】
    线程池之ThreadPool类与辅助线程
    Task.Run使用默认线程池
    VS生成事件
    线程池之ThreadPoolExecutor使用
    Sql笔记
  • 原文地址:https://www.cnblogs.com/lori/p/2490355.html
Copyright © 2020-2023  润新知