4.4. Блокировка и разблокировка документа

Источник здесь.[перевод не проверен];[перевёл Андрей Бушман]

    Необходимость в изменении объектов AutoCAD или доступе к ним может возникать в различных ситуациях и выполняются эти действия любым количеством приложений. За предотвращение конфликтов, которые могут возникнуть при параллельном доступе к данным, на вас возлагается ответственность по блокировке документа перед тем, как вы приступите к его изменению. Отказ от использования блокировки в определённых местах выполнения изменений может привести к нарушению блокировки во время модификации базы данных.

    Вам необходимо блокировать документ, когда ваше приложение выполняет следующие действия:
  • Взаимодействие с AutoCAD через немодальные диалоговые окна
  • Доступ к загруженным документам, отличным от текущего
  • Использование как COM сервер
  • Регистрация команды с командным флагом Session
    Например, когда вы добавляете примитив в пространство модели или листа документа, отличного от текущего, документ должен быть заблокирован. Вам следует использовать метод LockDocument объекта Database для блокировки. Вызов данного метода возвращает объект DocumentLock.

    После того, как вы выполните все необходимые изменения в базе данных, её следует разблокировать. Для разблокировки базы данных вы должны вызвать метод Dispose объекта DocumentLock. Вы так же можете использовать блок using с объявлением в нём объекта DocumentLock. При выходе из блока происходит разблокирование базы данных1.

Примечание:
    Когда происходит работа в процессе выполнения команды, которая не использует флаг Session, вам не нужно блокировать базу данных текущего документа перед началом модификации.

Блокирование базы данных чертежа перед изменением объекта

    Этот пример создаёт новый документ и затем чертит в нём окружность. После создания документа, его база данных блокируется, после чего в неё добавляется объект окружности. После добавления окружности база данных разблокируется и ассоциированное с ней окно документа устанавливается текущим.

Код VB.NET

   1:  Imports Autodesk.AutoCAD.ApplicationServices
   2:  Imports Autodesk.AutoCAD.DatabaseServices
   3:  Imports Autodesk.AutoCAD.Runtime
   4:  Imports Autodesk.AutoCAD.Geometry 
   5:   
   6:  <CommandMethod("LockDoc", CommandFlags.Session)> _
   7:  Public Sub LockDoc()
   8:   
   9:    '' Создание нового чертежа
  10:    Dim acDocMgr As DocumentCollection = Application.DocumentManager
  11:    Dim acNewDoc As Document = acDocMgr.Add("acad.dwt")
  12:    Dim acDbNewDoc As Database = acNewDoc.Database 
  13:   
  14:    '' Блокирование нового документа
  15:    Using acLckDoc As DocumentLock = acNewDoc.LockDocument() 
  16:   
  17:        '' Запуск транзакции в новой базе данных
  18:        Using acTrans As Transaction = acDbNewDoc.TransactionManager.StartTransaction() 
  19:   
  20:            '' Открытие таблицы блоков (Block table) для записи
  21:            Dim acBlkTbl As BlockTable
  22:            acBlkTbl = acTrans.GetObject(acDbNewDoc.BlockTableId, _
  23:                                         OpenMode.ForRead) 
  24:   
  25:            '' Открытие записи таблицы блоков (Block table) пространства модели (Model space) для записи
  26:            Dim acBlkTblRec As BlockTableRecord
  27:            acBlkTblRec = acTrans.GetObject(acBlkTbl(BlockTableRecord.ModelSpace), _
  28:                                            OpenMode.ForWrite) 
  29:   
  30:            '' Создание окружности с радиусом 3 мм в точке, с координатами (5,5)
  31:            Dim acCirc As Circle = New Circle()
  32:            acCirc.SetDatabaseDefaults()
  33:            acCirc.Center = New Point3d(5, 5, 0)
  34:            acCirc.Radius = 3 
  35:   
  36:            '' Добавление нового объекта в пространство модели (Model space) и в транзакцию
  37:            acBlkTblRec.AppendEntity(acCirc)
  38:            acTrans.AddNewlyCreatedDBObject(acCirc, True) 
  39:   
  40:            '' Сохранение нового объекта в базе данных
  41:            acTrans.Commit()
  42:        End Using
  43:   
  44:        '' Разблокирование документа
  45:    End Using 
  46:   
  47:    '' Установка нового документа текущим
  48:    acDocMgr.MdiActiveDocument = acNewDoc
  49:  End Sub

Код C#

   1:  using Autodesk.AutoCAD.ApplicationServices;
   2:  using Autodesk.AutoCAD.DatabaseServices;
   3:  using Autodesk.AutoCAD.Runtime;
   4:  using Autodesk.AutoCAD.Geometry; 
   5:   
   6:  [CommandMethod("LockDoc", CommandFlags.Session)]
   7:  public static void LockDoc()
   8:  {
   9:    // Создание нового чертежа
  10:    DocumentCollection acDocMgr = Application.DocumentManager;
  11:    Document acNewDoc = acDocMgr.Add("acad.dwt");
  12:    Database acDbNewDoc = acNewDoc.Database; 
  13:   
  14:    // Блокирование нового документа
  15:    using (DocumentLock acLckDoc = acNewDoc.LockDocument())
  16:    {
  17:        // Запуск транзакции в новой базе данных
  18:        using (Transaction acTrans = acDbNewDoc.TransactionManager.StartTransaction())
  19:        {
  20:            // Открытие таблицы блоков (Block table) для записи
  21:            BlockTable acBlkTbl;
  22:            acBlkTbl = acTrans.GetObject(acDbNewDoc.BlockTableId,
  23:                                         OpenMode.ForRead) as BlockTable; 
  24:   
  25:            // Открытие записи таблицы блоков (Block table) пространства модели (Model space) для записи
  26:            BlockTableRecord acBlkTblRec;
  27:            acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace],
  28:                                            OpenMode.ForWrite) as BlockTableRecord; 
  29:   
  30:            // Создание окружности, радиусом 3 мм, с центром в точке с координатами (5,5)
  31:            Circle acCirc = new Circle();
  32:            acCirc.SetDatabaseDefaults();
  33:            acCirc.Center = new Point3d(5, 5, 0);
  34:            acCirc.Radius = 3; 
  35:   
  36:            // Добавление нового объекта в пространство модели (Model space) и в транзакцию
  37:            acBlkTblRec.AppendEntity(acCirc);
  38:            acTrans.AddNewlyCreatedDBObject(acCirc, true); 
  39:   
  40:            // Сохранение нового объекта в базе данных
  41:            acTrans.Commit();
  42:        }
  43:   
  44:        // Разблокировка документа
  45:    } 
  46:   
  47:    // Установка нового документа текущим
  48:    acDocMgr.MdiActiveDocument = acNewDoc;
  49:  }

Примечания переводчика:
1 - т.к. для экземпляра DocumentLock автоматически вызывается метод Dispose

Comments