I'm having a problem which gives me a headache...
I made an app which runs for several hours, basicly an Open/Save tool which performs certain operations in files on our database.
Problem is, I get the exception mentioned in the subject from time to time. This seems to be a known issue and is caused by a multi-threaded program which tries to access a single threaded application.
As mentioned here:
...the solution to this problem is to implement the IOleMessageFilter. But now I'm running into a deadlock and my app retries the call forever. In other words, Edge is not recovering from the busy state.
Does anyone have experience with this kind of problem?
Solved! Go to Solution.
If you are familiar with my Samples for Solid Edge on CodePlex, I am adding a new OpenSave demo in the next release that I wrote recently. That demo utilizes executing OpenSave logic in separate AppDomains and is very robust. I recently tested it with 10K+ files and it worked perfect without even needing to restart Solid Edge.
If you want, I can share my code, its no secret. The Open/Save part is not the problem. The problem can occur everywhere in the code, as soon as the server is "busy".
I had the same problems too until I used the separate AppDomain technique. The next release of the Samples for Solid Edge is next monday and my OpenSave will be included. Hopefully that will help you get past the issue.
Thanks for your demo. I took a look at your code and it seems that you did something very similar to my approach. Still, the issue persists: When I lock the screen and unlock it an hour later or so, the app is stuck waiting for the call to be processed. Same happens when I connect to the computer running the program using RDP. I cannot just let the app run and leave the screen unlocked due to security reasons.
I'm uploading my solution, maybe someone can take a look and identify the problem at some point. For now I just have to process less files at once, so the processing time doesn't exceed 8 hours.
I took a look at your code. I don't see any separate AppDomain logic for Interop. If you're not using a separate AppDomain for Interop, you absolutely will have issues that youv've described.
I took another look at your demo. I'm having difficulties understanding the whole AppDomain concept and what you did in your code exactly.
From what I understand, the Open/Save part is being done in the "InteropProxy" class which is derived from MarshalByRefObject. Also, you create a new thread for each file you want to touch and in each thread you create a new InteropProxy object which then performs the Open/Save.
Thanks in advance
Yes, the actual automation logic happens inside the InteropProxy class that inherits from MarshalByRefObject. The reason for this is because I am creating a new AppDomain for each file that needs to be processed. The AppDomain gets created, an instance of the InteropProxy class is created inside the new AppDomain and executed. After execution, the AppDomain is immediately unloaded. Because .NET uses garbage collection (GC), objects cannot be deterministically released. There are .NET call that you can make to "suggest" GC but that alone is not enough to ensure freeing of objects when you demand it. My example is the only way to deterministically free any COM Interop wrappers and ensure that Solid Edge continues to function as expected.
Regading threading, there are two threads in my example. The first thread is a standard System.ComponentModel.BackgroundWorker that frees the UI from the main batch processing. The second thread that gets created is a System.Theading.Thread that handles the AppDomain creation and InteropProxy execution. The reason for the 2nd thread is to handle processing an individual file. The key reason to use a System.Threading.Thread in this particular instance is the requirement to set the threads apartment state to STA.
I don't follow your concern about using the "continue" statement in your processing. If you look at my example, I am actually doing similar types of filtering of files too. You just have to figure out where you need to put your filtering. If you need help, post your code with comments where you need help.