明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 3099|回复: 8

[讨论]这两种方法创建实体有什么不同?

[复制链接]
发表于 2005-8-2 23:34 | 显示全部楼层 |阅读模式

在.net开发ObjectARX程序时,可以使用两种方法来创建一个实体。可以手工操作块表、块表记录,将实体添加到模型空间的块表记录中,完成实体的创建:
[CommandMethod("CreateEnt")]
  static public void ZffCreateEnt() // This method can have any name
  {
   Point3d ptStart = new Point3d(0, 0, 0);
   Point3d ptEnd = new Point3d(100, 100, 0);
   Line line = new Line(ptStart, ptEnd);

   ObjectId btId = HostApplicationServices.WorkingDatabase.BlockTableId;
   BlockTable blkTbl = (BlockTable)btId.Open(OpenMode.ForRead);

   ObjectId btrId = blkTbl[BlockTableRecord.ModelSpace];
   BlockTableRecord blkTblRcd = (BlockTableRecord)btrId.Open(OpenMode.ForWrite);
   blkTbl.Close();

   ObjectId lineId = blkTblRcd.AppendEntity(line);
   blkTblRcd.Close();
   line.Close();
  }

Autodesk建议的方式是通过事物来辅助完成实体的创建:
[CommandMethod("CreateLine")]
  static public void ZffCreateLine()
  {
   Point3d startPoint = new Point3d(4.0, 2.0, 0.0);
   Point3d endPoint = new Point3d(10.0, 7.0, 0.0);
   Line line = new Line(startPoint,endPoint);
   ObjectId lineId;
  
   // 获得当前活动图形文档的图形数据库
   Database db=Application.DocumentManager.MdiActiveDocument.Database;
   // 获得事务管理器
   DBTransMan tm=db.TransactionManager;
   // 开始记录事物
   using(Transaction trans=tm.StartTransaction())
   {
    BlockTable bt=(BlockTable)tm.GetObject(db.BlockTableId,OpenMode.ForRead);

    BlockTableRecord btr=(BlockTableRecord)tm.GetObject(
     bt[BlockTableRecord.ModelSpace],OpenMode.ForWrite);

    // 将实体添加到图形数据库的块表记录中
    lineId=btr.AppendEntity(line);
    tm.AddNewlyCreatedDBObject(line,true);
    trans.Commit();

    trans.Dispose();
   }
  }

这两种方法有什么不同?欢迎大家发表自己的意见。

 楼主| 发表于 2005-8-2 23:34 | 显示全部楼层
从代码上来看,似乎仅仅是事务辅助处理时不需要手工关闭打开或者新建的对象(这一操作在VC++的ObjectARX中非常普遍)。
 楼主| 发表于 2005-8-2 23:58 | 显示全部楼层
大意了…编译的时候第一种方法通不过,开发教程中居然还有这样的代码,晕。发现Autodesk对.net开发的帮助文件极不负责,已经发现了不少错误。
发表于 2005-8-3 13:37 | 显示全部楼层
第一种方法是可以的,只不过编译的时候出现警告而已。
发表于 2005-8-11 13:26 | 显示全部楼层

事务在对连续操作出错时可以回滚,所以对添加块表记录和添加实体对象操作时使用事务包起来

呵呵,个人理解

发表于 2005-8-11 18:00 | 显示全部楼层

跟楼上想法一样

 楼主| 发表于 2005-8-12 10:13 | 显示全部楼层
楼上两位说的,在传统的ARX中确实如此,但是这里似乎并不是完全为了这个目的…
发表于 2005-8-13 10:54 | 显示全部楼层

以下内容是我译的关于事务的部分内容,完整译文在附件里,其中的问题请指出,共勉!

 

事务管理器概述

事务模式将多个客户对多个对象的若干个操作封装于个很小的动作中,它叫事务。在一个事务边界内,客户们可以通过对象的ID而获得指向它的指针。直到事务被用户结束或中止之前,对象的指针都是有效的。如果事务成功的结束,则所有对对象的操作都被提交;如果事务被中断则作用于对象上的操作也被取消。

采用这个机制完成的操作相对于常规的打开和关闭(详见第5章,《数据库对象》)办法有如下几个优点。打开关闭机制适用于对单个或少量对象的简单操作。而且,打开关闭机制在打开对象时有某些限制。例如,当一个对象打开用于读出,则此时你不能再打开用于写入。同样,当一个对象打开用于写入时,你不能同时打开用于读出。关于打开关闭对象时的一些可能引发的错误和限制见第5章。然而事务模式则显得更宽容,当对象与一个事务相关联之后,通过它的ID获得用于特定用途的对象指针一般都会成功。

Depending upon your application, there can be other disadvantages to using the open and close mechanism. If your application opens and closes the same object a number of times in the course of one operation—for example, a command—you'll incur serious inefficiencies due to these multiple opens and closes. A number of time-consuming operations are associated with closing an object. If you open an object for write, modify it, and then close it, the undo records of the modification are committed to the undo file, graphics for the object are generated, and notifications are fired. All these operations are performed every time the object is closed. If you transact your operation and obtain a pointer to the object using a transaction, all the activities mentioned above happen only once, at the end of the transaction. The result is improved efficiency and a smaller undo file, because the number of records going into the undo file is reduced.

当你开发某些应用程序时,采用打开关闭机制还可能有另外一些不便。如果程序在一个过程(比如一个命令)中多次打开、关闭同一个对象,由于这样的多次打开关闭操作应用程序的效率会很低。关闭对象伴随着很多是极耗时间的操作。当程序打开一个对象用于写入后,修改对象,然后关闭它,接着撤消操作的记录被写入到undo文件中,之后对象的图形重新生成,最后通知被发出。每一次关闭对象时,所有的这些动作都会随之而来。换成事务模式,如果采用事务,通过事务获得对象的指针,则(关闭多个对象后)上面提到的各项操作仅在事务的最后发生一次。事务机制提高了执行的效率,使得undo文件较小因为写入文件中的记录数减少了。

Also, if you have a complex network where objects refer to each other by object ID, you want to be able to obtain a pointer to an object in any module of your program without worrying if another module or another application has that object opened. These activities are only possible using the transaction model because transactions group operations and allow obtaining pointers from object IDs across module boundaries.

同时,如果有一组彼此之间通过ID相互引用的对象,你可以在任何一个模块中取得某个对象的指针而不用担心别的模块或程序已经将其打开了。这种行为只有采用事务机制才能实现,因为事务将多个操作集中在一起完成,而且能跨越模块的边界并可以借助对象ID而得到它的指针。

The transaction manager is a global manager object, similar to the editor, that is in charge of maintaining transactions. It is an instance of AcTransactionManager and is maintained in the system registry. You can obtain it from the system registry using the macro, which expands to

事务管理器是一个全局的管理对象(这与editor相似),作用是负责维护事务。它是AcTransactionManager的实例而且在系统注册表中管理。你可以用系统注册的宏actrTransactionManager 来取得它,如下 所示:

#define actrTransactionManager  \

AcTransactionManager::cast(

    acrxSysRegistry()->at(AC_TRANSACTION_MANAGER_OBJ))

The transaction manager should be used to start, end, or abort transactions. It can also provide information such as the number of active transactions at any moment (see the following section, MSITStore:E:\Downloads\docs\arxdev.chm::/xdg_214.html#388392" target="_blank" >Nesting Transactions) and a list of all the objects whose pointers have been obtained in all the transactions. The transaction manager maintains a list of reactors to notify clients of events such as the start, end, or abort of a transaction.

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x
发表于 2010-10-21 19:17 | 显示全部楼层
Very Good! 3Q
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-4-27 03:52 , Processed in 0.268716 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表