ADN Open CIS
Сообщество программистов Autodesk в СНГ

23/09/2014

Использование потоков (Thread) для фоновой обработки

Вопрос:

Внутри моей команды я хочу запустить фоновую задачу для синхронизации с базой данных. Как только эта задача заканчивается я хотел бы при помощи AutoCAD .NET API сделать некоторые изменения в базе данных. Однако, когда я вызываю функции AutoCAD API из этой задачи, они не работают. Например, the MdiActiveDocument равен null.

Ответ:

AutoCAD .NET API не позволяют использовать мультизадачность. Необходимо вызывать функции API из главной задачи.

Если вы находитесь в другой задаче, вам необходимо настроить вызов из главной задачи. Самый простой способ достичь этого – это создать объект System.Windows.Forms.Control в главной задаче и использовать его метод Invoke() для запуска функции которая и выполнит окончательную обработку.

Следующий пример показывает это:

Код - C#: [Выделить]
  1. using System;
  2. using Autodesk.AutoCAD.Runtime;
  3. using System.Windows.Forms;
  4. using Autodesk.AutoCAD.EditorInput;
  5. using acApp = Autodesk.AutoCAD.ApplicationServices.Application;
  6. using Autodesk.AutoCAD.ApplicationServices;
  7. using Autodesk.AutoCAD.DatabaseServices;
  8. using Autodesk.AutoCAD.Geometry;
  9.  
  10. namespace BackgroundProcess
  11. {
  12.   public class Commands : IExtensionApplication
  13.   {
  14.     static Control syncCtrl;
  15.     public void Initialize()
  16.     {
  17.       // Создаем элемент управления для перенаправления
  18.       // вызова в главную задачу
  19.       syncCtrl = new Control();
  20.       syncCtrl.CreateControl();
  21.     }
  22.  
  23.     public void Terminate()
  24.     {
  25.     }
  26.  
  27.     void BackgroundProcess()
  28.     {
  29.       // Это чтобы продемонстрировать фоновый процесс
  30.       System.Threading.Thread.Sleep(5000);
  31.  
  32.       // Теперь нужно перенаправить вызов в главную задачу
  33.       // Я не знаю в каком случае может быть false в этом контексте,
  34.       // но на всякий случай проверяю
  35.       if (syncCtrl.InvokeRequired)
  36.         syncCtrl.Invoke(
  37.           new FinishedProcessingDelegate(FinishedProcessing));
  38.       else
  39.         FinishedProcessing();
  40.     }
  41.  
  42.     delegate void FinishedProcessingDelegate();
  43.     void FinishedProcessing()
  44.     {
  45.       // Если мы хотим модифицировать базу данных, в этом случае
  46.       // мы должны заблокировать документ, как в контексте приложения
  47.       Document doc = acApp.DocumentManager.MdiActiveDocument;
  48.       using (doc.LockDocument())
  49.       {
  50.         using (Transaction tr =
  51.           doc.Database.TransactionManager.StartTransaction())
  52.         {
  53.           BlockTable bt =
  54.             (BlockTable)tr.GetObject(
  55.             doc.Database.BlockTableId, OpenMode.ForRead);
  56.  
  57.           BlockTableRecord ms = (BlockTableRecord)tr.GetObject(
  58.             bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
  59.  
  60.           Line line =
  61.             new Line(new Point3d(0, 0, 0), new Point3d(10, 10, 0));
  62.           ms.AppendEntity(line);
  63.           tr.AddNewlyCreatedDBObject(line, true);
  64.  
  65.           tr.Commit();
  66.         }
  67.       }
  68.  
  69.       // Так же напишем в командную строку
  70.       Editor ed = acApp.DocumentManager.MdiActiveDocument.Editor;
  71.       ed.WriteMessage("Фоновая задача завершилась!\n");
  72.     }
  73.  
  74.     [CommandMethod("ProcessInBackground")]
  75.     public void ProcessBackground()
  76.     {
  77.       // Допустим, что мы получили какие-то данные из чертежа
  78.       // и хотим их обработать в фоновой задаче
  79.       System.Threading.Thread thread =
  80.         new System.Threading.Thread(
  81.           new System.Threading.ThreadStart(BackgroundProcess));
  82.       thread.Start();
  83.  
  84.       Editor ed = acApp.DocumentManager.MdiActiveDocument.Editor;
  85.       ed.WriteMessage(
  86.         "Фоновая обработка запущена." + 
  87.         "Можете работать как обычно.\n");
  88.     }
  89.   }
  90. }

 

Источник: http://adndevblog.typepad.com/autocad/2012/06/use-thread-for-background-processing.html

Обсуждение: http://adn-cis.org/forum/index.php?topic=973

Опубликовано 23.09.2014