Hello!
I´m getting .NET exception on Microstation V8I Selectseries 4 (08.11.09.867) [using bentley map 08.11.09.862] with strange behavior.
It happens when I try to drop my complex elements (features). Of course to accept the drop operation, a window is displayed:
Everything works fine if I click Yes(by that I mean complex elements are dropped without errors or crashes), but problem occurs if I decide to press No. After clicking this option, I receive unhandled .NET exception:
Somehow I managed to find a suitable workaround to fix that, as I read in this link, it might be caused by some docked windows. So I investigated more and found out that if I close the project explorer window(that is opened and docked by default when new UPF is created), the error is no longer present. It even does not matter if I open the project explorer window again, the problem is gone forever. (only weird thing is that even after clicking No, the message center says the element has been dropped, even though I pressed No - so it looks like it dropped it in some temporary state no matter what I choose).
However, I was wondering, if there is some explanation why is that happening or how to avoid this.
PS: I also tried .NET repair tool
Thanks in advance for answers.
Update1:
I found out that the .NET exception is being thrown after I undo the last action made (so basically drop of the element), as I react to changed state of the element. According to that, I´m changing also subject of this question from Microstation V8I .NET exception after closing a window to Microstation V8I .NET exception after undoing dropped element.
Workaround still works though. After I close the docked Project explorer window, the problem is no longer present.
1. Actually I didn´t pay much attention to the possibility of "bad" element creation, as everything works fine, except this one particular case. And even with that, after applying my workaround (I mention it in question), the problem disappears.
2. I setup a callback to CHANGE_TRACK_FUNC_Changed. Thats when I spawn my dialog, because it means the user might have dropped some of the elements. During that callback, I spawn my dialog. After declining this operation I undo the last action (that is drop). The exception is not thrown exactly after the mdlUndo function call, but after my callback ends and the flow goes back to the microstation code.
Jan Šlegr said:How and when you set undo buffer?
Do you mean mdlUndo_SetActive(true)? If yes, then its before I start even the callback.
Jan Šlegr said:In what transaction context you are modifying DGN file?
Could you explain this further please?
Lubo B said:And even with that, after applying my workaround (I mention it in question), the problem disappears.
No, the problem not disappear in my opinion, because problem is (probably) in your code.
Of course, a possibility that something is wrong in Bentley Map itself, but because it seems nobody else has reported such issue (personally, I did not see it at any from my BM users), BM code is fine.
Lubo B said:I setup a callback to CHANGE_TRACK_FUNC_Changed.
Franky, I have become dissappointed by this discussion and I tend to leave it. This discussion is several days old, it contains several answers and comments already, and for the first time such crucial information is shared? When you are not willing to provide complete detail information and any piece of your code (so it's absolutely not clear what your code does), how can you expect anybody can help you? Sorry, but from my perspective it looks like wasted time.
To use these types of callback is quite sensitive. And to try to change anything requires to know all implications and consequences, because it can easily happen to be intrusive.
Lubo B said:After declining this operation I undo the last action (that is drop).
Are you sure? Without knowing code, context (data structure) and testing, I can guess only (because unfortunately my knowledge is probably not good enough).
What I would think about: You mentioned you used "DGN only" project, so I expect every element is treated as feature, native or through DFS mechanism. In this context, what is "last action"? From a user perspective, it's "to drop an element", when icon is clicked and confirmed. In terms of visible elements, it's represented by more steps, because new elements are created and the complex element is deleted. Internally, it's even more complicated, because when the element is feature, XAttributes are attached to it. And because XAttributes are "on element", stored somewhere else in DGN file (I guess it's in dedicated stream, but it's technical detail), Drop tool has to schedule XAttributes removal to not corrupt data integrity. I even think some operations are done in asynchronous way.
I do not know when, in this complex process, your callback is called (when graphical element is changed, after complete operation...?) and what is treated as undo action. To call undo can be both perfectly fine, but also invalidating something, that causes the exception alter.
Lubo B said:Do you mean mdlUndo_SetActive(true)?
Probably this my question was not important, because when we discuss Drop element tool, this tool is responsible to set how undo buffer is set.
Lubo B said:Could you explain this further please?
I recommend (because it's mandatory knowledge today) to study Transaction Manager (TxnMonitor class) documenation in MicroStationAPI help.
File changes are processed as transactions, controlled by Transaction Manager, to ensure data is created and modified in a correct way. Plus, it helps to manage Undo steps in users friendly way, because complex operation, internally represented by e.g. tens of even hundreds of operations, is written at once. Also consequent individual operations can be grouped into one transaction group.
In fact, any interaction with DGN file goes through and is processed by Transaction Manager.
Lubo B said:because it means the user might have dropped some of the elements.
In my opinion it's too late, because the callback is called when element is (I guess) dropped already and the new data is in DgnCache already. So when XFM element is dropped, many operations were finished.
I am not sure what is the best way how to solve such situation. At first, because you are in Bentley Map (which is not MicroStation, but more complex environment), you can check BM SDK documentation whether some from callback provided by BM API does not suits your needs better. Also, I recommend to change the code to use modern Transaction Manager. I think many operations are equal (ending at the same code), but Transaction Manager API always work in the transaction context. A third way can be to block to use Drop element tool before (not after) elements are dropped. It can be achieved by monitoring input queue. Disadvantage is that command ids are not strictly fixed, so they can change in future (but it's not as big issue as it can looks like).
With regards,
Jan
Bentley Accredited Developer: iTwin Platform - AssociateLabyrinth Technology | dev.notes() | cad.point
Jan Šlegr said:A third way can be to block to use Drop element tool before (not after) elements are dropped. It can be achieved by monitoring input queue. Disadvantage is that command ids are not strictly fixed, so they can change in future (but it's not as big issue as it can looks like).
Do you mean that there is a specific command generated when user tries to drop an element?
I´ve tried that method using the mdlInput_setMonitorFunction(MONITOR_ALL).
The problem is that I´m able to react only when user starts using Drop element tool (keyin "DROP" is passed to the queue). There is no specific command generated when user confirms selected element and is dropping it.
I can then only listen to mouse click, but it includes all clicks (left button), no matter if there is selected element or not.