SoFunction
Updated on 2025-04-06

Share the problem that I encountered at work that caused RCW to be unable to be released under multiple threads

Recently, a colleague encountered a problem when calling a method in a class library. The exception information is as follows:

An attempt to free the RCW that is being used, an active thread or other thread is being used, an attempt to free the RCW that is being used will result in corruption or data loss.

This method performs related operations on word files. Because I have called this method in a multi-threaded environment before and have not encountered this problem, my colleague asked me to go over and see what happened. After performing related operations on the file, another method will be called to release the word object. Some of the codes are as follows:

Word._Application t = oWord as Word._Application;
object oIsSave = false;
(ref oIsSave, ref oMissing, ref oMissing);
(oDoc);
(oWord);
oWord = null;
oDoc = null;
();
();

This code is to ensure that the word object is released immediately and the word process is closed. Because the exception information is located here, I started to look at it here after I went over, but after looking at it for a long time, I couldn't see any problems with the methods in the class library. Because I didn't encounter this situation before, I think it might not be the problem here, and the product I was responsible for has undergone a lot of tests, so there is definitely no problem, so I said let me see how you called it, open his code and take a look. There was no other problem overall, but one thing caught my attention. The instantiation of this class in the code is placed in the global scope. Because it is a CSS project, doing so will cause the object to be always referenced, so it cannot be released even during garbage collection. The com component is called here, which causes the word process to be unable to be closed, and colleagues use multi-threading here, so once the program runs, a lot of word processes will not be closed. So the object here is instantiated into the thread method, so that after the method execution is completed, the objects in the heap are in a reference-free state and are released during garbage collection, and the problem is solved naturally. In fact, it doesn’t matter whether it is single thread or multi-threading. It mainly instantiates it within the global scope, which causes the object to be garbage collected. Therefore, you must pay attention to the life cycle of the object when writing code.