I have a situation where revit is throwing an unmanaged error and I think I know why it is happening from reading Jeremy's blog posts on similar issues.
So, I have an external command that kicks off a Backgroundworker to download data from a database. The control return to Revit after the backgroundworker is kicked on. I am using a backgroundworker so my users would not have to wait until the data download is complete. I am subscribing to backgroundworker completed event to make some changes to the document. Revit API throws the error at this event. Here is what is likely happening:
1) The application/document objects are being disposed before the backgroundworker completed event is raised. I have made sure that I am pushing these objects to a static class, so they are available when the worker completes running. So this should not be an issue.
2) Multithreading should not be an issue because the background worker completed event should run on the same thread from where it is initialized. I am initializing it from the Revit thread.
3) From what I can figure out, Revit API does not like to be called from anywhere outside the standard events (external command, application start-up etc.). Is this right?
A possible workaround could be to execute a plug-in on demand from the backgroundworker completed event so the API calls stay within the confines. However, I cannot figure out a way from the documentation on how to execute an external command from other than the standard button click. Is this possible.
Could there be any workaround/solution for this. Thanks.
First of all...
"Multithreading should not be an issue because the background worker completed event should run on the same thread from where it is initialized. I am initializing it from the Revit thread."
...hope you are 100% sure about this because othervise this is the main source of your problem.
"From what I can figure out, Revit API does not like to be called from anywhere outside the standard events (external command, application start-up etc.). Is this right?"
I can't say anything sure but this sound quite obvious to me. I think Revit API works a bit like "Flyweight" pattern. During external commands etc. the API provides access to document via temporary objects which are removed when they aro not used anymore (add-in scope/execution ended etc.).
Could you use Revit's iddling event to handle this? You could raise some flag when the download is completed and then in the iddling event handler you could check this flag...?
Thanks for your response. It looks like using the idling event is the way to go in my situation. I have done some prototypes using the idling event before and for some reason noticed it to be a bit slower compared to external command interface. I will have to see how it affects this particular scenario.
Regarding your first comment on Backgroundworker, I hope this is not a concern as according to the documentation of the class, the completed event should be raised on the same thread from where it is initialized, saving me of the troubles with thread pooling etc.