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

ADN Club => AutoCAD .NET API => Тема начата: Александр Пекшев aka Modis от 26-01-2016, 14:33:57

Название: Перестает работать функция (обработчик событий)
Отправлено: Александр Пекшев aka Modis от 26-01-2016, 14:33:57
Всем привет. Заголовок темы не совсем корректный, по причине того, что я даже и не знаю ЧТО перестает работать  :D

В общих чертах работа функции:
1. Обработка события завершения команды - запоминаем нужные объекты (примитивы)
2. Обработка события добавления объекта в БД чертежа - запомненные объекты изменяются как мне нужно
3. Значение "вкл/выкл" функции хранится в XData чертежа
4. При переключении документов читается значение из XData чертежа, чтобы включить/выключить работу функции

В общем проблема в том, что я не знаю в чем проблема :D
Как таковых ошибок не возникает (try{}catch{} ничего не ловит). Функция работает, работает, работает, а потом в какой-то момент бац - и перестает работать. ПРЕДПОЛОЖИТЕЛЬНО дело связано с переключение между документами (еще вариант - переключение между моделью и листом). Чтобы заставить функцию работать снова приходится закрывать документ и открывать заново

Вырезал из кода основные моменты. Где-то тут и происходит стопор:
Код - C# [Выбрать]
  1. using Autodesk.AutoCAD.ApplicationServices;
  2. using Autodesk.AutoCAD.DatabaseServices;
  3.  
  4. namespace ClassLibrary2
  5. {
  6.     public class Class1
  7.     {
  8.         public void Initialize()
  9.         {
  10.             Application.DocumentManager.DocumentCreated += DocumentManager_DocumentCreated;
  11.         }
  12.  
  13.         private void DocumentManager_DocumentCreated(object sender, DocumentCollectionEventArgs e)
  14.         {
  15.             // Чтение данных из расширенных данных чертежа
  16.             // код не привожу, т.к. для вопроса не важен
  17.             if (!MpCadHelpers.HasXDataDictionary("MP_LayerToEnt"))
  18.                 return;
  19.             if (MpCadHelpers.GetStringXData("MP_LayerToEnt").Equals("ON"))
  20.             {
  21.                 MpLayerAutoFunctions.LayerAutoIsEventOn = true;
  22.                 this.On();
  23.             }
  24.             else
  25.             {
  26.                 MpLayerAutoFunctions.LayerAutoIsEventOn = false;
  27.                 this.Off();
  28.             }
  29.         }
  30.  
  31.         // Коллекция ObjectId
  32.         public ObjectIdCollection ObjCol;
  33.         // Переменная служит для определения включена ли работа функции
  34.         public static bool LayerAutoIsEventOn;
  35.  
  36.         public void On()
  37.         {
  38.             // Создаем новую коллекцию ObjectId
  39.             ObjCol = new ObjectIdCollection();
  40.             //
  41.             LayerAutoIsEventOn = true;
  42.             // Включаем обработчики событий
  43.             Application.DocumentManager.MdiActiveDocument.Database.ObjectAppended += CallBack_ObjectAppended;
  44.             Application.DocumentManager.MdiActiveDocument.CommandEnded += CallBack_CommandEnded;
  45.             Application.DocumentManager.MdiActiveDocument.CommandCancelled += CallBack_CommandEnded;
  46.             Application.DocumentManager.MdiActiveDocument.CommandFailed += MdiActiveDocument_CommandFailed;
  47.             Application.DocumentManager.DocumentActivated += DocumentManager_DocumentActivated;
  48.         }
  49.         private void DocumentManager_DocumentActivated(object sender, DocumentCollectionEventArgs e)
  50.         {
  51.             // Очищаем список
  52.             ObjCol?.Clear();
  53.             // В переменную записывается значение из расширенных данных чертежа
  54.             // код не привожу, т.к. он не важен (в случае отсутсвия данных возвращает false)
  55.             LayerAutoIsEventOn = MpCadHelpers.GetStringXData("MP_LayerToEnt").Equals("ON");
  56.         }
  57.         // Отключение работы функции
  58.         public void Off()
  59.         {
  60.             // "Обнуляем" переменные
  61.             ObjCol = null;
  62.             LayerAutoIsEventOn = false;
  63.             // Отключаем обработчики событий
  64.             Application.DocumentManager.MdiActiveDocument.Database.ObjectAppended -= CallBack_ObjectAppended;
  65.             Application.DocumentManager.MdiActiveDocument.CommandEnded -= CallBack_CommandEnded;
  66.             Application.DocumentManager.MdiActiveDocument.CommandCancelled -= CallBack_CommandEnded;
  67.             Application.DocumentManager.MdiActiveDocument.CommandFailed -= MdiActiveDocument_CommandFailed;
  68.             Application.DocumentManager.DocumentActivated -= DocumentManager_DocumentActivated;
  69.         }
  70.         private void CallBack_CommandEnded(object sender, CommandEventArgs e)
  71.         {
  72.             if (!LayerAutoIsEventOn)
  73.                 return;
  74.             // Дальше код программы. Для вопроса не важен
  75.         }
  76.         // Команда завершилась неудачно
  77.         private void MdiActiveDocument_CommandFailed(object sender, CommandEventArgs e)
  78.         {
  79.             // Очищаем список
  80.             ObjCol?.Clear();
  81.         }
  82.         // Обработка события добавления объекта в БД чертежа
  83.         private void CallBack_ObjectAppended(object sender, ObjectEventArgs e)
  84.         {
  85.             if (!LayerAutoIsEventOn)
  86.                 return;
  87.             // Дальше код программы. Для вопроса не важен
  88.         }
  89.     }
  90. }

P.S. Работаю на 2016 автокаде. В более ранних проверить не могу
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Александр Ривилис от 26-01-2016, 14:50:48
3. Значение "вкл/выкл" функции хранится в XData чертежа
???
1. Обработка события завершения команды - запоминаем нужные объекты (примитивы)
2. Обработка события добавления объекта в БД чертежа - запомненные объекты изменяются как мне нужно
Обычно всё наоборот - в событии добавления в базу запоминают объекты, а в событии завершения команды их обрабатывают.
По коду ничего сказать не могу. Тут надо сидеть с отладчиком.
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Александр Пекшев aka Modis от 26-01-2016, 15:08:39
по поводу XData - проблем никогда вроде не возникало. Сейчас через декомпилятор посмотрел код - примерно такой:
Код - C# [Выбрать]
  1. public static string GetStringXData(string dictionaryName)
  2.         {
  3.             Document mdiActiveDocument = Application.DocumentManager.MdiActiveDocument;
  4.             if (mdiActiveDocument == null) return string.Empty;
  5.  
  6.             Database database = mdiActiveDocument.Database;
  7.             try
  8.             {
  9.                 using (mdiActiveDocument.LockDocument())
  10.                 {
  11.                     using (Transaction transaction = database.TransactionManager.StartTransaction())
  12.                     {
  13.                         ObjectId at = ((DBDictionary)transaction.GetObject(database.NamedObjectsDictionaryId, (OpenMode)1, true)).GetAt(dictionaryName);
  14.                         Xrecord xrecord = transaction.GetObject(at, (OpenMode)1, true) as Xrecord;
  15.                         string str = string.Empty;
  16.                         if (xrecord != null)
  17.                         {
  18.                             foreach (TypedValue typedValue in xrecord.Data.AsArray())
  19.                             {
  20.                                 str = @typedValue.Value.ToString();
  21.                             }
  22.                         }
  23.                         transaction.Commit();
  24.                         return str;
  25.                     }
  26.                 }
  27.             }
  28.             catch
  29.             {
  30.                 return string.Empty;
  31.             }
  32.         }
Честно - я уже и не помню где это брал. Там еще пару методов. Но проблем никогда не было.
Обычно всё наоборот - в событии добавления в базу запоминают объекты, а в событии завершения команды их обрабатывают
Верно. Это я просто напутал немного ))
По коду ничего сказать не могу. Тут надо сидеть с отладчиком
Вот тут и самая "засада" - сидел с отладчиком не один раз. Если бы проблему можно было вызвать или хотя-бы причину возникновения...
По факту - я могу работать в автокаде не один час - и все нормально. Много раз пытался поймать момент когда функция перестает работать - тщетно. Только вот подозрение и осталось на переключение между документами (или моделью/листом) - когда работаю с несколькими документами, то "поломка" происходит быстрее

Тему создал уже от безысходности. Надеюсь, что просто чей-нибудь опыт, чья-нибудь догадка/предположение помогут
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Александр Ривилис от 26-01-2016, 15:14:10
3. Значение "вкл/выкл" функции хранится в XData чертежа
Xrecord xrecord = transaction.GetObject(at, (OpenMode)1, true) as Xrecord;
Да уж. И где у тебя XData???
1) Если ты только читаешь из чертежа, то LockDocument() не нужен. Более того в момент переключения чертежа может не сработать.
2) Попробуй убрать из кода транзакцию - можно легко без неё обойтись.
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Привалов Дмитрий от 26-01-2016, 15:14:16
я даже и не знаю ЧТО перестает работать
Лучше всего добавить логгирование в файл. Или запустить автокад в режиме отладки и проверить переменные.

Возможно порядок событий не так срабатывает, как ты ожидаешь. Например ты отлавливаешь
DocumentCreated
а потом сразу привязываешься к
MdiActiveDocument
DocumentActivated
а не факт что документ создался, и успел стать активным, т.е. привязка произошла к активному в данный момент документу предыдущего чертежа.
Что также может сказаться на проверке. MpCadHelpers.GetStringXData("MP_LayerToEnt").Equals("ON")
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Александр Пекшев aka Modis от 26-01-2016, 15:18:58
а не факт что документ создался, и успел стать активным, т.е. привязка произошла к активному в данный момент документу предыдущего чертежа
Интересная идея. Звучит вполне разумно - буду тестить
Но сразу возникает вопрос - если и так, то что тогда делать? О_о
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Привалов Дмитрий от 26-01-2016, 15:21:29
если и так, то что тогда делать?
Скорее всего подписаться на DocumentActivated
...но это я все так, в теории.
Лучше всего Алексанра Ривилиса повыспрашивать про очередность событий документов ;-)
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Александр Ривилис от 26-01-2016, 15:31:12
Лучше всего Алексанра Ривилиса повыспрашивать про очередность событий документов ;-)
Есть четкое правило - никогда не рассчитывать на очередность событий редактора/документов.
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Привалов Дмитрий от 26-01-2016, 15:36:15
Возможно в public void On()
при череде удачных MpCadHelpers.GetStringXData("MP_LayerToEnt").Equals("ON")
Ты можешь несколько раз подписать функции, и они будут срабатывать по несколько раз.
Ну тут нужно про события обновить знания)
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Привалов Дмитрий от 26-01-2016, 15:39:41
Есть четкое правило - никогда не рассчитывать на очередность событий редактора/документов.
Т.е. сначала может для чертежа сработать DocumentActivated, а потом DocumentCreated?
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Александр Пекшев aka Modis от 26-01-2016, 15:40:04
Наш диалог натолкнул меня на мысль - переделать немного логику функции:
в события DocumentCreated и DocumentActivated запихнуть подписывание на события завершения команд и добавления объектов. А вот в них уже проверять - включена функция или нет.
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Александр Ривилис от 26-01-2016, 15:52:11
В любом случае и в DocumentCreated и в DocumentActivated ты дожен брать данные из e.Document, а не из MDIActiveDocument.
Т.е. функцию чтения нужно переписать так, чтобы она принимала в качестве еще одного аргумента Document (или Database - это уже на твоё усмотрение).
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Дмитрий Загорулькин от 26-01-2016, 18:10:08
Я сталкивался с тем, что события перестают обрабатываться, если в методе обработки возникает исключение. Это исключение может перехватить какой-нибудь try-catch, но это делу не помогает. Действительно, спасает только открытие чертежа заново или перезапуск автокада. Скорее всего, здесь то же самое - какое-то трудно отлавливаемое исключение.
Совет - сделайте вывод какого-нибудь предупреждения при попадании в блок catch. Хоть в консоль, хоть в виде MessageBox-AlertMessage. Тогда будет хотя бы ясно, в какой момент происходит сбой.
И еще, я в свое время пришел к выводу, что лучше обрабатывать событие DocumentActivated вместо DocumentCreated. Вроде бы, у меня с ним тоже были какие-то проблемы...
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Дмитрий Загорулькин от 26-01-2016, 18:26:11
Вот, кстати, как вариант того, что могло случиться:
http://adn-cis.org/forum/index.php?topic=743.msg3986#msg3986
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Александр Пекшев aka Modis от 31-01-2016, 23:44:53
В общем - я человек ленивый)) И разбираться с проблемами документов мне не захотелось
В итоге я переделал немного принцип работы. Для тестов нужно много времени, но вроде все работает нормально
Код - C# [Выбрать]
  1. public static ObjectIdCollection ObjCol;
  2. public static List<string> AcadCommands;
  3. public void Initialize()
  4. {
  5.     AcApp.DocumentManager.MdiActiveDocument.Database.ObjectAppended += CallBack_ObjectAppended;
  6.     AcApp.DocumentManager.MdiActiveDocument.CommandEnded += CallBack_CommandEnded;
  7.     AcApp.DocumentManager.MdiActiveDocument.CommandCancelled += CallBack_CommandEnded;
  8.     AcApp.DocumentManager.MdiActiveDocument.CommandFailed += MdiActiveDocument_CommandFailed;
  9.     //
  10.     AcApp.DocumentManager.DocumentActivated += DocumentManager_DocumentActivated;
  11.     AcApp.DocumentManager.DocumentCreated += DocumentManager_DocumentCreated;
  12. }
  13. public void Terminate()
  14. {
  15.     // Ничего не нужно
  16. }
  17. private static void DocumentManager_DocumentActivated(object sender, DocumentCollectionEventArgs e)
  18. {
  19.     // Очищаем список
  20.     ObjCol?.Clear();
  21.     if (e.Document != null)
  22.     {
  23.         e.Document.Database.ObjectAppended += CallBack_ObjectAppended;
  24.         e.Document.CommandEnded += CallBack_CommandEnded;
  25.         e.Document.CommandCancelled += CallBack_CommandEnded;
  26.         e.Document.CommandFailed += MdiActiveDocument_CommandFailed;
  27.     }
  28. }
  29.  
  30. static void DocumentManager_DocumentCreated(object sender, DocumentCollectionEventArgs e)
  31. {
  32.     // Очищаем список
  33.     ObjCol?.Clear();
  34.     if (e.Document != null)
  35.     {
  36.         e.Document.Database.ObjectAppended += CallBack_ObjectAppended;
  37.         e.Document.CommandEnded += CallBack_CommandEnded;
  38.         e.Document.CommandCancelled += CallBack_CommandEnded;
  39.         e.Document.CommandFailed += MdiActiveDocument_CommandFailed;
  40.     }
  41. }
  42. public static void On()
  43. {
  44.     MpCadHelpers.SetStringXData("MP_LayerToEnt", "ON");
  45. }
  46. public static void Off()
  47. {
  48.     ObjCol = null;
  49.     MpCadHelpers.SetStringXData("MP_LayerToEnt", "OFF");
  50. }
  51. private static void MdiActiveDocument_CommandFailed(object sender, CommandEventArgs e)
  52. {
  53.     // Очищаем список
  54.     ObjCol?.Clear();
  55. }
  56. // Обработка события добавления объекта в базу чертежа
  57. private static void CallBack_ObjectAppended(object sender, ObjectEventArgs e)
  58. {
  59.     // Код для примера не важный
  60. }
  61. // Обработка события завершения команды автокада
  62. private static void CallBack_CommandEnded(object sender, CommandEventArgs e)
  63. {
  64.     if (MpCadHelpers.GetStringXData("MP_LayerToEnt").Equals("ON"))
  65.     {
  66.        // Далее код для примера не важный
  67.     }
  68. }
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Дмитрий Загорулькин от 01-02-2016, 12:46:38
Что-то я принципиальной разницы с исходным вариантом не увидел :)
В методе Initialize 100% надо делать проверку AcApp.DocumentManager.MdiActiveDocument на null.
Не увидел, где эти объекты создаются:
Код - C# [Выбрать]
  1. public static ObjectIdCollection ObjCol;
  2. public static List<string> AcadCommands;
И я бы не стал для своей коллекции ObjectId использовать ObjectIdCollection. Тот же List<ObjectId> гораздо удобнее.
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Александр Пекшев aka Modis от 01-02-2016, 12:52:28
Что-то я принципиальной разницы с исходным вариантом не увидел
А вот принципиальная разница есть! И еще какая! Но пока все толком не протестирую - точно не скажу
Не увидел, где эти объекты создаются:
Для вопроса это было не суть важно) Где они создаются - стерто
И я бы не стал для своей коллекции ObjectId использовать ObjectIdCollection. Тот же List<ObjectId> гораздо удобнее.
Начинал делать это очень давно. Сейчас уже и не скажу почему взял ObjectIdCollection. Скорее от отсутствия опыта) В принципе - особо роли не играет - Linq'ом пользоваться не приходится
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Привалов Дмитрий от 01-02-2016, 13:07:13
В общем - я человек ленивый)) И разбираться с проблемами документов мне не захотелось
нет ты трудоголик, не любящий отдыхать в выходные и не любящий спать по ночам выискивая ошибки, сделанные по лени!

 
Ты можешь несколько раз подписать функции, и они будут срабатывать по несколько раз.

Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Привалов Дмитрий от 01-02-2016, 15:22:23
В общем - я человек ленивый)) И разбираться с проблемами документов мне не захотелось
нет ты трудоголик, не любящий отдыхать в выходные и не любящий спать по ночам выискивая ошибки, сделанные по лени!

 
Ты можешь несколько раз подписать функции, и они будут срабатывать по несколько раз.

...не успевал дописать, кипишь на работе. Так вот
в DocumentManager_DocumentActivated() ты к примеру  подписываешь
e.Document.Database.ObjectAppended += CallBack_ObjectAppended;

В случае, если ты попереключаешься между 2 документами туда-сюда три раза, произойдут события DocumentActivated и ты попросишь программу три раза вызывать функцию CallBack_ObjectAppended при добавлении объекта в чертеже. И в итоге получишь тормоза при добавлении объекта, и возможно сбой логики программы, в зависимости от того, что делают твои функции.

не ленись на событиях, их сложно отлаживать.))))
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Александр Пекшев aka Modis от 01-02-2016, 15:48:09
В случае, если ты попереключаешься между 2 документами туда-сюда три раза, произойдут события DocumentActivated и ты попросишь программу три раза вызывать функцию CallBack_ObjectAppended при добавлении объекта в чертеже. И в итоге получишь тормоза при добавлении объекта, и возможно сбой логики программы, в зависимости от того, что делают твои функции.
Кхм....... надо потестить
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Дмитрий Загорулькин от 01-02-2016, 16:36:54
...не успевал дописать, кипишь на работе. Так вот
в DocumentManager_DocumentActivated() ты к примеру  подписываешь
e.Document.Database.ObjectAppended += CallBack_ObjectAppended;

В случае, если ты попереключаешься между 2 документами туда-сюда три раза, произойдут события DocumentActivated и ты попросишь программу три раза вызывать функцию CallBack_ObjectAppended при добавлении объекта в чертеже. И в итоге получишь тормоза при добавлении объекта, и возможно сбой логики программы, в зависимости от того, что делают твои функции.

не ленись на событиях, их сложно отлаживать.))))
Поэтому, я всегда пишу так:
e.Document.Database.ObjectAppended -= CallBack_ObjectAppended;
e.Document.Database.ObjectAppended += CallBack_ObjectAppended;
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Александр Пекшев aka Modis от 01-02-2016, 16:39:12
Дмитрий Загорулькин, я когда читал твой предыдущий ответ точно о том-же подумал: сделать сначала отключение, потов подключение. Теперь бы найти время все это применить и потестить)
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Александр Пекшев aka Modis от 02-02-2016, 15:16:20
Дмитрий Загорулькин, даже не учитывая вышеизложенное (что события сработают по несколько раз) - второй вариант, который я описал выше, не сработал - со временем все опять перестало работать ((
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Дмитрий Загорулькин от 02-02-2016, 17:32:51
В блоки catch добавлял вывод сообщений?
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Александр Пекшев aka Modis от 02-02-2016, 17:38:54
В блоки catch добавлял вывод сообщений?
В том-то и дело - нужно еще найти куда этот try catch расположить! В том, коде, что я пропустил - там есть. Ошибок не возникает
Остается вариант - расположить try catch вообще везде и затестить ))

Думаю, сегодня верну первый вариант (который в первом сообщении), внесу несколько изменений и буду продолжать тестировать. Второй вариант более "тяжелый", т.к. чаще приходится читать расширенные данные
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Дмитрий Загорулькин от 02-02-2016, 19:51:54
Скорее всего, достаточно во все уже имеющиеся блоки добавить, а не новых расставить. AutoCAD настолько нежен, что при любом исключении валится. Иногда, правда, просто предупреждение выдаст - мол: "имеется ошибка, продолжить?". В любом случае, тихо такие события не проходят. А вот если это все в try-catch, то краха не происходит, но события уже работать перестают. Тут только остается понять в каком блоке это происходит и при каких манипуляциях, ставить туда точку остановки при отладке, воспроизводить ситуацию и смотреть что там не так.
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Александр Пекшев aka Modis от 02-02-2016, 20:02:48
Дмитрий Загорулькин, ты немного не понял (или я не понял) - в try catch у меня не "тихое проглатывание". Если ошибка - выскакивает соответствующее окошко. Так вот в имеющихся try catch ошибок нет. Вот и придется новых натыкивать (хотя-бы временно), чтобы хотя-бы найти где происходит сбой. Потом уже разбираться - почему

И главное - другие пользователи не сообщают об этом. Такое ощущение, что я один работаю с несколькими документами и запущенной функцией =) Ну или просто ленивые - не пишут
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Дмитрий Загорулькин от 02-02-2016, 20:08:47
Если выскакивает окошко и точно известна последовательность действий, приводящих к ошибке - тогда совсем все просто должно быть. Запускаем приложение в отладке и добиваемся возникновения ошибки. Окошко об ошибке должно появится информативное, с указанием точного места возникновения ошибки - вплоть до номера строки в файле с кодом.
А пользователи очень часто игнорируют такие вещи. Откуда им знать, из-за чего возникла ошибка. AutoCAD и сам по себе фаталит иногда.
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Александр Пекшев aka Modis от 13-02-2016, 10:01:41
В общем - так я ничего и не добился. Пробовал все различные варианты, почти все оборачивал в try catch - безрезультатно. Просто после (НЕИЗВЕСТНЫХ) действий при работе автокада перестают работать обработчики событий ДОКУМЕНТА. Помогает полное закрытие документа с последующим открытием. Никаких ошибок не ловится
Выделил два слова
- неизвестных - думал, что проблема в переключении между чертежами, но сегодня произошел сбой, а работал я только с одним чертежом
- документа - сбой происходит только в одном документе. Если перейти в другой, где активны те-же события - там работает все
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Привалов Дмитрий от 13-02-2016, 13:43:23
В общем - так я ничего и не добился. Пробовал все различные варианты, почти все оборачивал в try catch - безрезультатно. Просто после (НЕИЗВЕСТНЫХ) действий при работе автокада перестают работать обработчики событий ДОКУМЕНТА. Помогает полное закрытие документа с последующим открытием. Никаких ошибок не ловится
Выделил два слова
- неизвестных - думал, что проблема в переключении между чертежами, но сегодня произошел сбой, а работал я только с одним чертежом
- документа - сбой происходит только в одном документе. Если перейти в другой, где активны те-же события - там работает все
не удалось полениться?))))
try catch врятли поможет, т.к. ошибка скорее касается всего времени выполнения.
Открывай поток и пиши информацию о  событиях, на которые подписываешься в текстовый файл и анализируй.
Ищи нарушение очередности или двойное срабатывание, может что еще найдешь.
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Александр Пекшев aka Modis от 22-05-2017, 14:32:58
Недавно наткнулся на одну статью и вспомнил эту тему - http://drive-cad-with-code.blogspot.ru/2015/10/be-careful-when-handling-document-events.html
Цитата из статьи:
Цитировать
Also, when running the code, when the application changes from the state of command event being handled to the state of command event handler being lost, there is no exception being raised so that the application crashes.
Т.е. не только я с таким столкнулся (моя проблема и по сей день актуальна). Со временем работы в автокаде обработчики просто перестают работать. При этом не возникает Exception и понять причины - практически невозможно
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Дмитрий Загорулькин от 22-05-2017, 15:33:43
При этом не возникает Exception
Exception возникает, но Автокад его молча проглатывает. Надо просто найти в каком месте.
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Александр Пекшев aka Modis от 22-05-2017, 15:35:07
При этом не возникает Exception
Exception возникает, но Автокад его молча проглатывает. Надо просто найти в каком месте.
Отладкой это невозможно. Нужно придумать какой-то костыль для отлова причины
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Дмитрий Загорулькин от 22-05-2017, 15:37:06
Возможно. Дебаг - это то еще шаманство :)
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Александр Пекшев aka Modis от 22-05-2017, 15:40:07
Возможно. Дебаг - это то еще шаманство :)
Невозможно в том плане, что ошибка может проявиться через 5 минут работы или через 4 часа работы. А может вообще не проявиться. Т.е. для отладки нужно знать точные события, которые к этому приводят, чтобы их можно было повторить при отладке. А вот эти события поймать - это как-раз придумать тот самый костыль
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Дмитрий Загорулькин от 22-05-2017, 15:58:16
Что-то я не учел, что меня можно иначе понять. Я имел в виду, что "да, ВОЗМОЖНО (может быть, наверное) надо придумать какой-то костыль", а не пытался опровергнуть утверждение об использовании отладки.  :)
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: simson43 от 22-01-2019, 15:41:07
вот и я наткнулся на эту проблему.
и если в этом событии возникает ошибка (искусственная, теста ради, необрабатываемая) метод завершается без каких либо упоминаний об этом, а после этого это событие не срабатывает вообще!
если же место ошибки в try catch обернуть, то ошибка обрабатывается и даже событие потом вызывается.
но вот в рабочем коде, с блоком try catch даже, с дебагером все проходит гладко от начала до конца, не попадая в блок catch, но видимо где то тихо все равно рушится и событие перестает работать(при чем метод, вызываемый из события, вне событий ошибок не выдает обычно)
так и не нашел в чем дело.

мб спустя время кто то нашел причину?
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Александр Ривилис от 22-01-2019, 15:49:38
мб спустя время кто то нашел причину?
Универсальной причины нет.
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Дмитрий Загорулькин от 22-01-2019, 15:50:08
и если в этом событии возникает ошибка
В каком "этом" событии?
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: simson43 от 22-01-2019, 16:00:35
В каком "этом" событии?
XrefBeginAttached или XrefSubCommandEnd
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Дмитрий Загорулькин от 22-01-2019, 16:13:37
но вот в рабочем коде, с блоком try catch даже, с дебагером все проходит гладко от начала до конца, не попадая в блок catch, но видимо где то тихо все равно рушится и событие перестает работать(при чем метод, вызываемый из события, вне событий ошибок не выдает обычно)
:o
Что-то я не понял. Если всё так - тогда надо в другом месте искать сбой.
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: simson43 от 22-01-2019, 16:30:46
метод закомментирую - все работает (не т е обработчик не слетает)
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Александр Ривилис от 22-01-2019, 16:32:47
Видимо что-то недопустимое делаешь в этом обработчике. Причем недопустимое именно в контексте этого события.
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Дмитрий Загорулькин от 22-01-2019, 16:44:46
метод закомментирую - все работает (не т е обработчик не слетает)
Мда... При таком объёме предоставляемой информации - могу только пожелать успехов в решении проблемы. Что комментируете, где - попробуй угадай. Всё надо вытягивать наводящими вопросами.
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: simson43 от 22-01-2019, 17:02:23
да в этом событии обрабатывал обновленные ссылки (выгружал например если необходимо)
и снова срабатывало это событие, НО выходило из него при первой же проверке (в событии XrefSubCommandEnd):
Код - C# [Выбрать]
  1. if (e.xrefOp != XrefOperation.XrefReloadOperation) return;
и больше не попадало в это событие

но отключив это событие на время выполнения метода падать перестало.
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Александр Ривилис от 22-01-2019, 17:05:16
да в этом событии обрабатывал обновленные ссылки (выгружал например если необходимо)
А ты не понимаешь, что этого делать нельзя?

(https://c1.staticflickr.com/9/8598/15980478802_71afe0bab2_m.jpg)
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: simson43 от 22-01-2019, 19:18:02
Ну они же уже обновились,, действие законченно, разве не могу выгрузить?
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Александр Ривилис от 22-01-2019, 20:14:20
Ну они же уже обновились,, действие законченно, разве не могу выгрузить?
Нет. Найди другое событие для этого.
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: simson43 от 22-01-2019, 20:34:59
В чем криминал? Работает ж по итогу

Какое событие его может заменить в таком случае?
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Александр Ривилис от 22-01-2019, 20:38:57
В чем криминал? Работает ж по итогу
Где же работает, если ты сам пишешь что перестаёт работать. Ты уж определись как-нибудь.
Какое событие его может заменить в таком случае?
Тут нужно проверять. Возможно Document.CommandEnded, возможно Application.Idle
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: simson43 от 22-01-2019, 21:10:31
Я использу это событие XrefSubCommandEnd
Я же сказал если отключить отбработчик на время выполнения инструкций то все работает! Ничего не падает, все гладко)
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Александр Ривилис от 22-01-2019, 21:49:12
simson43,
Тебе очень повезло. Не каждое событие в AutoCAD .NET API можно отключить внутри другого события. У нас на форуме это обсуждалось.
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: simson43 от 22-01-2019, 21:52:20
Так законно то что а накрутил?
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Александр Ривилис от 22-01-2019, 21:54:34
Так законно то что а накрутил?
Законно всё что работает, не разваливает AutoCAD и не конфликтует с другими сторонними приложениями. Но я бы сделал так, как написал выше ибо риск всё-равно остаётся.
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: simson43 от 22-01-2019, 21:55:16
Нашел статью. Обработчики статические. Поэтому наверное работает?
Название: Re: Перестает работать функция (обработчик событий)
Отправлено: Александр Ривилис от 22-01-2019, 21:56:43
Нашел статью. Обработчики статические. Поэтому наверное работает?
Причина не в этом.