Перестает работать функция (обработчик событий)

Автор Тема: Перестает работать функция (обработчик событий)  (Прочитано 20353 раз)

0 Пользователей и 2 Гостей просматривают эту тему.

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Всем привет. Заголовок темы не совсем корректный, по причине того, что я даже и не знаю ЧТО перестает работать  :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 автокаде. В более ранних проверить не могу

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
3. Значение "вкл/выкл" функции хранится в XData чертежа
???
1. Обработка события завершения команды - запоминаем нужные объекты (примитивы)
2. Обработка события добавления объекта в БД чертежа - запомненные объекты изменяются как мне нужно
Обычно всё наоборот - в событии добавления в базу запоминают объекты, а в событии завершения команды их обрабатывают.
По коду ничего сказать не могу. Тут надо сидеть с отладчиком.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
по поводу 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.         }
Честно - я уже и не помню где это брал. Там еще пару методов. Но проблем никогда не было.
Обычно всё наоборот - в событии добавления в базу запоминают объекты, а в событии завершения команды их обрабатывают
Верно. Это я просто напутал немного ))
По коду ничего сказать не могу. Тут надо сидеть с отладчиком
Вот тут и самая "засада" - сидел с отладчиком не один раз. Если бы проблему можно было вызвать или хотя-бы причину возникновения...
По факту - я могу работать в автокаде не один час - и все нормально. Много раз пытался поймать момент когда функция перестает работать - тщетно. Только вот подозрение и осталось на переключение между документами (или моделью/листом) - когда работаю с несколькими документами, то "поломка" происходит быстрее

Тему создал уже от безысходности. Надеюсь, что просто чей-нибудь опыт, чья-нибудь догадка/предположение помогут

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
3. Значение "вкл/выкл" функции хранится в XData чертежа
Xrecord xrecord = transaction.GetObject(at, (OpenMode)1, true) as Xrecord;
Да уж. И где у тебя XData???
1) Если ты только читаешь из чертежа, то LockDocument() не нужен. Более того в момент переключения чертежа может не сработать.
2) Попробуй убрать из кода транзакцию - можно легко без неё обойтись.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Привалов Дмитрий

  • ADN Club
  • *****
  • Сообщений: 533
  • Карма: 117
я даже и не знаю ЧТО перестает работать
Лучше всего добавить логгирование в файл. Или запустить автокад в режиме отладки и проверить переменные.

Возможно порядок событий не так срабатывает, как ты ожидаешь. Например ты отлавливаешь
DocumentCreated
а потом сразу привязываешься к
MdiActiveDocument
DocumentActivated
а не факт что документ создался, и успел стать активным, т.е. привязка произошла к активному в данный момент документу предыдущего чертежа.
Что также может сказаться на проверке. MpCadHelpers.GetStringXData("MP_LayerToEnt").Equals("ON")

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
а не факт что документ создался, и успел стать активным, т.е. привязка произошла к активному в данный момент документу предыдущего чертежа
Интересная идея. Звучит вполне разумно - буду тестить
Но сразу возникает вопрос - если и так, то что тогда делать? О_о

Оффлайн Привалов Дмитрий

  • ADN Club
  • *****
  • Сообщений: 533
  • Карма: 117
если и так, то что тогда делать?
Скорее всего подписаться на DocumentActivated
...но это я все так, в теории.
Лучше всего Алексанра Ривилиса повыспрашивать про очередность событий документов ;-)

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Лучше всего Алексанра Ривилиса повыспрашивать про очередность событий документов ;-)
Есть четкое правило - никогда не рассчитывать на очередность событий редактора/документов.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Привалов Дмитрий

  • ADN Club
  • *****
  • Сообщений: 533
  • Карма: 117
Возможно в public void On()
при череде удачных MpCadHelpers.GetStringXData("MP_LayerToEnt").Equals("ON")
Ты можешь несколько раз подписать функции, и они будут срабатывать по несколько раз.
Ну тут нужно про события обновить знания)

Оффлайн Привалов Дмитрий

  • ADN Club
  • *****
  • Сообщений: 533
  • Карма: 117
Есть четкое правило - никогда не рассчитывать на очередность событий редактора/документов.
Т.е. сначала может для чертежа сработать DocumentActivated, а потом DocumentCreated?

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Наш диалог натолкнул меня на мысль - переделать немного логику функции:
в события DocumentCreated и DocumentActivated запихнуть подписывание на события завершения команд и добавления объектов. А вот в них уже проверять - включена функция или нет.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
В любом случае и в DocumentCreated и в DocumentActivated ты дожен брать данные из e.Document, а не из MDIActiveDocument.
Т.е. функцию чтения нужно переписать так, чтобы она принимала в качестве еще одного аргумента Document (или Database - это уже на твоё усмотрение).
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Я сталкивался с тем, что события перестают обрабатываться, если в методе обработки возникает исключение. Это исключение может перехватить какой-нибудь try-catch, но это делу не помогает. Действительно, спасает только открытие чертежа заново или перезапуск автокада. Скорее всего, здесь то же самое - какое-то трудно отлавливаемое исключение.
Совет - сделайте вывод какого-нибудь предупреждения при попадании в блок catch. Хоть в консоль, хоть в виде MessageBox-AlertMessage. Тогда будет хотя бы ясно, в какой момент происходит сбой.
И еще, я в свое время пришел к выводу, что лучше обрабатывать событие DocumentActivated вместо DocumentCreated. Вроде бы, у меня с ним тоже были какие-то проблемы...

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Вот, кстати, как вариант того, что могло случиться:
http://adn-cis.org/forum/index.php?topic=743.msg3986#msg3986

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
В общем - я человек ленивый)) И разбираться с проблемами документов мне не захотелось
В итоге я переделал немного принцип работы. Для тестов нужно много времени, но вроде все работает нормально
Код - 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. }

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Что-то я принципиальной разницы с исходным вариантом не увидел :)
В методе Initialize 100% надо делать проверку AcApp.DocumentManager.MdiActiveDocument на null.
Не увидел, где эти объекты создаются:
Код - C# [Выбрать]
  1. public static ObjectIdCollection ObjCol;
  2. public static List<string> AcadCommands;
И я бы не стал для своей коллекции ObjectId использовать ObjectIdCollection. Тот же List<ObjectId> гораздо удобнее.

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Что-то я принципиальной разницы с исходным вариантом не увидел
А вот принципиальная разница есть! И еще какая! Но пока все толком не протестирую - точно не скажу
Не увидел, где эти объекты создаются:
Для вопроса это было не суть важно) Где они создаются - стерто
И я бы не стал для своей коллекции ObjectId использовать ObjectIdCollection. Тот же List<ObjectId> гораздо удобнее.
Начинал делать это очень давно. Сейчас уже и не скажу почему взял ObjectIdCollection. Скорее от отсутствия опыта) В принципе - особо роли не играет - Linq'ом пользоваться не приходится

Оффлайн Привалов Дмитрий

  • ADN Club
  • *****
  • Сообщений: 533
  • Карма: 117
В общем - я человек ленивый)) И разбираться с проблемами документов мне не захотелось
нет ты трудоголик, не любящий отдыхать в выходные и не любящий спать по ночам выискивая ошибки, сделанные по лени!

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


Оффлайн Привалов Дмитрий

  • ADN Club
  • *****
  • Сообщений: 533
  • Карма: 117
В общем - я человек ленивый)) И разбираться с проблемами документов мне не захотелось
нет ты трудоголик, не любящий отдыхать в выходные и не любящий спать по ночам выискивая ошибки, сделанные по лени!

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

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

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

не ленись на событиях, их сложно отлаживать.))))

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
В случае, если ты попереключаешься между 2 документами туда-сюда три раза, произойдут события DocumentActivated и ты попросишь программу три раза вызывать функцию CallBack_ObjectAppended при добавлении объекта в чертеже. И в итоге получишь тормоза при добавлении объекта, и возможно сбой логики программы, в зависимости от того, что делают твои функции.
Кхм....... надо потестить

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
...не успевал дописать, кипишь на работе. Так вот
в DocumentManager_DocumentActivated() ты к примеру  подписываешь
e.Document.Database.ObjectAppended += CallBack_ObjectAppended;

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

не ленись на событиях, их сложно отлаживать.))))
Поэтому, я всегда пишу так:
e.Document.Database.ObjectAppended -= CallBack_ObjectAppended;
e.Document.Database.ObjectAppended += CallBack_ObjectAppended;

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Дмитрий Загорулькин, я когда читал твой предыдущий ответ точно о том-же подумал: сделать сначала отключение, потов подключение. Теперь бы найти время все это применить и потестить)

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Дмитрий Загорулькин, даже не учитывая вышеизложенное (что события сработают по несколько раз) - второй вариант, который я описал выше, не сработал - со временем все опять перестало работать ((

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
В блоки catch добавлял вывод сообщений?

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
В блоки catch добавлял вывод сообщений?
В том-то и дело - нужно еще найти куда этот try catch расположить! В том, коде, что я пропустил - там есть. Ошибок не возникает
Остается вариант - расположить try catch вообще везде и затестить ))

Думаю, сегодня верну первый вариант (который в первом сообщении), внесу несколько изменений и буду продолжать тестировать. Второй вариант более "тяжелый", т.к. чаще приходится читать расширенные данные

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Скорее всего, достаточно во все уже имеющиеся блоки добавить, а не новых расставить. AutoCAD настолько нежен, что при любом исключении валится. Иногда, правда, просто предупреждение выдаст - мол: "имеется ошибка, продолжить?". В любом случае, тихо такие события не проходят. А вот если это все в try-catch, то краха не происходит, но события уже работать перестают. Тут только остается понять в каком блоке это происходит и при каких манипуляциях, ставить туда точку остановки при отладке, воспроизводить ситуацию и смотреть что там не так.

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Дмитрий Загорулькин, ты немного не понял (или я не понял) - в try catch у меня не "тихое проглатывание". Если ошибка - выскакивает соответствующее окошко. Так вот в имеющихся try catch ошибок нет. Вот и придется новых натыкивать (хотя-бы временно), чтобы хотя-бы найти где происходит сбой. Потом уже разбираться - почему

И главное - другие пользователи не сообщают об этом. Такое ощущение, что я один работаю с несколькими документами и запущенной функцией =) Ну или просто ленивые - не пишут

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Если выскакивает окошко и точно известна последовательность действий, приводящих к ошибке - тогда совсем все просто должно быть. Запускаем приложение в отладке и добиваемся возникновения ошибки. Окошко об ошибке должно появится информативное, с указанием точного места возникновения ошибки - вплоть до номера строки в файле с кодом.
А пользователи очень часто игнорируют такие вещи. Откуда им знать, из-за чего возникла ошибка. AutoCAD и сам по себе фаталит иногда.

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
В общем - так я ничего и не добился. Пробовал все различные варианты, почти все оборачивал в try catch - безрезультатно. Просто после (НЕИЗВЕСТНЫХ) действий при работе автокада перестают работать обработчики событий ДОКУМЕНТА. Помогает полное закрытие документа с последующим открытием. Никаких ошибок не ловится
Выделил два слова
- неизвестных - думал, что проблема в переключении между чертежами, но сегодня произошел сбой, а работал я только с одним чертежом
- документа - сбой происходит только в одном документе. Если перейти в другой, где активны те-же события - там работает все

Оффлайн Привалов Дмитрий

  • ADN Club
  • *****
  • Сообщений: 533
  • Карма: 117
В общем - так я ничего и не добился. Пробовал все различные варианты, почти все оборачивал в try catch - безрезультатно. Просто после (НЕИЗВЕСТНЫХ) действий при работе автокада перестают работать обработчики событий ДОКУМЕНТА. Помогает полное закрытие документа с последующим открытием. Никаких ошибок не ловится
Выделил два слова
- неизвестных - думал, что проблема в переключении между чертежами, но сегодня произошел сбой, а работал я только с одним чертежом
- документа - сбой происходит только в одном документе. Если перейти в другой, где активны те-же события - там работает все
не удалось полениться?))))
try catch врятли поможет, т.к. ошибка скорее касается всего времени выполнения.
Открывай поток и пиши информацию о  событиях, на которые подписываешься в текстовый файл и анализируй.
Ищи нарушение очередности или двойное срабатывание, может что еще найдешь.

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Недавно наткнулся на одну статью и вспомнил эту тему - 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 и понять причины - практически невозможно

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
При этом не возникает Exception
Exception возникает, но Автокад его молча проглатывает. Надо просто найти в каком месте.

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
При этом не возникает Exception
Exception возникает, но Автокад его молча проглатывает. Надо просто найти в каком месте.
Отладкой это невозможно. Нужно придумать какой-то костыль для отлова причины

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Возможно. Дебаг - это то еще шаманство :)

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Возможно. Дебаг - это то еще шаманство :)
Невозможно в том плане, что ошибка может проявиться через 5 минут работы или через 4 часа работы. А может вообще не проявиться. Т.е. для отладки нужно знать точные события, которые к этому приводят, чтобы их можно было повторить при отладке. А вот эти события поймать - это как-раз придумать тот самый костыль

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Что-то я не учел, что меня можно иначе понять. Я имел в виду, что "да, ВОЗМОЖНО (может быть, наверное) надо придумать какой-то костыль", а не пытался опровергнуть утверждение об использовании отладки.  :)

Оффлайн simson43

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
вот и я наткнулся на эту проблему.
и если в этом событии возникает ошибка (искусственная, теста ради, необрабатываемая) метод завершается без каких либо упоминаний об этом, а после этого это событие не срабатывает вообще!
если же место ошибки в try catch обернуть, то ошибка обрабатывается и даже событие потом вызывается.
но вот в рабочем коде, с блоком try catch даже, с дебагером все проходит гладко от начала до конца, не попадая в блок catch, но видимо где то тихо все равно рушится и событие перестает работать(при чем метод, вызываемый из события, вне событий ошибок не выдает обычно)
так и не нашел в чем дело.

мб спустя время кто то нашел причину?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
мб спустя время кто то нашел причину?
Универсальной причины нет.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
и если в этом событии возникает ошибка
В каком "этом" событии?

Оффлайн simson43

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
В каком "этом" событии?
XrefBeginAttached или XrefSubCommandEnd

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
но вот в рабочем коде, с блоком try catch даже, с дебагером все проходит гладко от начала до конца, не попадая в блок catch, но видимо где то тихо все равно рушится и событие перестает работать(при чем метод, вызываемый из события, вне событий ошибок не выдает обычно)
:o
Что-то я не понял. Если всё так - тогда надо в другом месте искать сбой.

Оффлайн simson43

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
метод закомментирую - все работает (не т е обработчик не слетает)

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Видимо что-то недопустимое делаешь в этом обработчике. Причем недопустимое именно в контексте этого события.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
метод закомментирую - все работает (не т е обработчик не слетает)
Мда... При таком объёме предоставляемой информации - могу только пожелать успехов в решении проблемы. Что комментируете, где - попробуй угадай. Всё надо вытягивать наводящими вопросами.

Оффлайн simson43

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
да в этом событии обрабатывал обновленные ссылки (выгружал например если необходимо)
и снова срабатывало это событие, НО выходило из него при первой же проверке (в событии XrefSubCommandEnd):
Код - C# [Выбрать]
  1. if (e.xrefOp != XrefOperation.XrefReloadOperation) return;
и больше не попадало в это событие

но отключив это событие на время выполнения метода падать перестало.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
да в этом событии обрабатывал обновленные ссылки (выгружал например если необходимо)
А ты не понимаешь, что этого делать нельзя?

Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн simson43

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Ну они же уже обновились,, действие законченно, разве не могу выгрузить?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Ну они же уже обновились,, действие законченно, разве не могу выгрузить?
Нет. Найди другое событие для этого.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн simson43

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
В чем криминал? Работает ж по итогу

Какое событие его может заменить в таком случае?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
В чем криминал? Работает ж по итогу
Где же работает, если ты сам пишешь что перестаёт работать. Ты уж определись как-нибудь.
Какое событие его может заменить в таком случае?
Тут нужно проверять. Возможно Document.CommandEnded, возможно Application.Idle
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн simson43

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Я использу это событие XrefSubCommandEnd
Я же сказал если отключить отбработчик на время выполнения инструкций то все работает! Ничего не падает, все гладко)

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
simson43,
Тебе очень повезло. Не каждое событие в AutoCAD .NET API можно отключить внутри другого события. У нас на форуме это обсуждалось.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн simson43

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Так законно то что а накрутил?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Так законно то что а накрутил?
Законно всё что работает, не разваливает AutoCAD и не конфликтует с другими сторонними приложениями. Но я бы сделал так, как написал выше ибо риск всё-равно остаётся.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн simson43

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Нашел статью. Обработчики статические. Поэтому наверное работает?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Нашел статью. Обработчики статические. Поэтому наверное работает?
Причина не в этом.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение