ahopera 发表于 2009-10-10 16:50:00

[讨论]trans的两种用法

在Kean的blog里,他喜欢采用using(trans)
{
...........
}
我在CAD的DTV里,发现负责讲解的工程师,多采用dim trans as......=
try

    'if success then commit trans
    trans.commit()
catch
    'add some code
finally
    'if get error then dispose trans
    trans.dispose()
end try
谈一下我对两者的看法,using的好处是可以省掉一个trans.dispose(),但用try.....end try 则可以对错误进行判断
在我对ARX函数的学习过程中,发现对图元操作的函数,往住是带一个状态返回值。在.Net Api写进行arx托管程序时,我们一般采用对objectid的操作,需要大量使用trans,一般创建图元需要返回图元对象或objectid,操作对象则不需要返回值。
例如对图元移动,则可以用
sub MoveEnt(EntID as Objectid,StartPnt as Point3d,EndPnt as Point3d)
但是,有的这个函数会出错,例如需要对图形中的一些定义过的图元进行操作。
比如:你创建了一些曲线,把曲线的handler存在字典里,在以后用的时候把handler转换成objectid进行使用。有时候用户在操作图形的时候把这些曲线的图层锁定了,当你操作这一系列图元时,会导致一个eonlockedlayer的错误,如果用using trans,会直接出错然后退出。但是,很可能这些曲线是你经过检查后认为不需要操作或不能操作才锁定的,同时即使出现错误也可以进行对其它图元操作,你的程序将无法达到你想要的目的。
而如果你用了try的话,完全可以将过程(C#里的void Function)写成一个函数:
Function MoveEnt(EntID as Objectid,StartPnt as Point3d,EndPnt as Point3d) As Boolean
在转换时可以在这样写try
    ent=trans.GetObject
    ''Add MoveEntCode
   trans.Commit()
    Return True '成功变换返回真
Catch
    Return False '变换失败返回假
Finally
    trans.Dispose()
End Try
我觉得在逻辑上,用try要严密些
同时在调用上,也可以采用无返回值的调用,也可以采用有返回值的调用。

雪山飞狐_lzh 发表于 2009-10-10 18:48:00

using语句内部一样可以用try的
      
      static public void MMove()
      {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            PromptSelectionResult res = ed.GetSelection();
            if (res.Status == PromptStatus.OK)
            {
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                  foreach (ObjectId id in res.Value.GetObjectIds())
                  {
                        Move(
                            (Entity)id.GetObject(OpenMode.ForRead),
                            Point3d.Origin,
                            new Point3d(10,10,0)
                            );
                  }
                  tr.Commit();
                }
            }
      }

      static public bool Move(Entity ent, Point3d startPoint, Point3d endPoint)
      {
            try
            {
                ent.UpgradeOpen();
                ent.TransformBy(Matrix3d.Displacement(endPoint - startPoint));
            }
            catch
            {
                return false;
            }
            return true;
      }

ahopera 发表于 2009-10-10 20:44:00

那是,我只是觉得,当封装在函数里的时候,用using就会重复了,用我的想法,是

      
      static public void MMove()
      {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            PromptSelectionResult res = ed.GetSelection();
            if (res.Status == PromptStatus.OK)
            {
                foreach (ObjectId id in res.Value.GetObjectIds())
                {
                  Move(id,
                        Point3d.Origin,
                        new Point3d(10, 10, 0)
                        );
                }
             }
      }
      static public bool Move(ObjectId entid, Point3d startPoint, Point3d endPoint)
      {
            Transaction tr = entid.Database.TransactionManager.StartTransaction();
            try
            {
                Entity ent = (Entity)tr.GetObject(entid, OpenMode.ForWrite);
                ent.TransformBy(Matrix3d.Displacement(endPoint - startPoint));
                tr.Commit();
                return true;
            }
            catch
            {
                return false;
            }
            finally
            {
                tr.Dispose();
            }
      }上面的的缺点是trans重新用了n次,效率较差,但是封装性较高
学到了一点,我用Objectid.GetObject总是出错,原来是要放在trans里面
页: [1]
查看完整版本: [讨论]trans的两种用法