bert 发表于 2013-9-4 02:24:51

我假设下面的代码示例的工作方式与WILL HATCH建议的相同?
(它涉及通过一个参数传递“活动”事务)
Function main()
...
Using Transaction tr = db.TransactionManager.StartTransaction()
Dim DbObjectCollection blocks = get_blocks(db, tr)
sort_blocks(blocks)
...
End Using
End Function
Function get_Blocks(db As Database, tr as Transaction) As DbObjectCollection
If tr == null Then throw new ArgumentNullException( "Function called outside the scope of transaction" )
...get blocks
End Function
话又说回来,熟练使用事务通过参数接收事务的每个方法可能不是那么可取的。
*编辑*
使用事务 tr = db。TransactionManager.StartTransaction()
我显然说:
Dim Transaction tr = db。TransactionManager.TopTransaction
*/EDIT*
看起来更容易接受

bert 发表于 2013-9-4 03:45:10

首先
欢迎来到沼泽伯特
您使用的是垂直命令吗?因为我记得Will使用的是MEP或其他不同的命令,但他发现它会为每个自定义命令创建一个事务
此外,任何需要或希望使用事务的方法都不需要传递事务
如果您后退一步查看,AutoCAD将执行您的代码的入口点只有这么多。
-初始化
-命令
—事件
-,否决
,等等,
并可以更改需要处理的方式
如果不注意使用嵌套或大量事务,则只能部分更改数据
需要休息一下,但当更好地了解需求时,有人可以帮助重构代码,以及如何在一个事务中封装方法。

bert 发表于 2013-9-4 09:44:11

感谢杰夫的欢迎!
你用我用“垂直”是什么意思?
如前所述,我的代码确实早就应该进行一些重构了。
我听从了WILL HATCH的建议,将所有操作都保留在1笔交易中。
这花了一些工作,但结果如下:
Sub Main()
      ' Get the current document and database
      Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
      Dim acCurDb As Database = acDoc.Database
      ' Lock the document
      Using acLckDoc As DocumentLock = acDoc.LockDocument()
            ' Start a transaction
            Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
               
                Call function1()
                dim obj as DbObject = function2()
                If TypeOf (obj) Is BlockReference Then
                      Call function3(obj)
                end if
                ' Save the changes
                acTrans.Commit()
            End Using ' Transaction
      End Using ' Lock
End Sub
Function method1()
      ' Get the current document and database
      Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
      Dim acCurDb As Database = acDoc.Database
      Dim acTrans As Transaction = db.TransactionManager.TopTransaction
      Dim blkTable As BlockTable = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead)
      If blkTable.Has(_blockName) Then
            ......
      End If
End Function
Function method2() as DBObject
      ' Get the current document and database
      Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
      Dim acCurDb As Database = acDoc.Database
      Dim acTrans As Transaction = db.TransactionManager.TopTransaction
      Dim pPtOpts As PromptEntityOptions = New PromptEntityOptions("")
      ' Prompt for the start point
      pPtOpts.Message = vbLf & _prompt
      pPtOpts.AllowNone = False
      Dim pPtRes As PromptEntityResult = acDoc.Editor.GetEntity(pPtOpts)
      ' Exit if the user presses ESC or cancels the command
      If pPtRes.Status = PromptStatus.Cancel Then Return Nothing
      Return acTrans.GetObject(pPtRes.ObjectId, OpenMode.ForRead)
End Function
sub method3(_blkRef as BlockReference)
       ' Get the current document and database
      Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
      Dim acCurDb As Database = acDoc.Database
      Dim acTrans As Transaction = db.TransactionManager.TopTransaction
      Dim attCol As AttributeCollection = _blkRef.AttributeCollection
      For Each attId As ObjectId In attCol
             Dim attRef As AttributeReference = DirectCast(acTrans.GetObject(attId, OpenMode.ForWrite), AttributeReference)
             Dim recievedValue As String = get_AttVal(attRef.Tag, _attVals)
             If Not String.IsNullOrEmpty(recievedValue) Then attRef.TextString = recievedValue
      Next
End sub

目前我遇到了与管理大量事务,管理单个事务完全相反的麻烦:
我正在左右回避以下错误:
“由于对象的当前状态,操作无效。
我有代码想要在同一事务的早期打开ForRead的对象上Allready已经准备好打开ForRead/Write。
也许我正在使这种方式变得复杂?

n.yuan 发表于 2013-9-4 10:25:12

通过垂直,我的意思是
Civil3D,Autocad Arch,AutoCAD MEP等。添加到 AutoCAD 或扩展 AutoCAD 的产品。

必须找到一份工作,但稍后会发布一些东西,或者其他人会发布更好的东西。

n.yuan 发表于 2013-9-4 10:35:58

不,我是在100%纯AutoCAD背景下编写.NET的
替换我在过去5年为我工作的公司编写的400页VBA代码。(不要问)
页: 1 [2]
查看完整版本: .IsDynamicBlock 返回 false ?