Share the problems I encountered in my work that caused RCW to be unable to release under multithreading

  • 2021-08-31 08:51:37
  • OfStack

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

Attempts to release an RCW in use, an RCW in use on an active thread or another thread, and an attempt to release an RCW in use can result in corruption or data loss.

The word file is related to this method, because I have called this method in a multithreaded environment before and have not encountered this problem, so my colleague asked me to go over and see what happened. This method will call another method to release the word object after the related operation on the file. Part of the code is as follows:


Word._Application t = oWord as Word._Application;
object oIsSave = false;
t.Quit(ref oIsSave, ref oMissing, ref oMissing);
System.Runtime.InteropServices.Marshal.ReleaseComObject(oDoc);
System.Runtime.InteropServices.Marshal.ReleaseComObject(oWord);
oWord = null;
oDoc = null;
GC.Collect();
GC.Collect();

This code is intended to ensure that the word object is immediately released and the word process is shut down. Because the exception information is located here, So when I went over, I started looking at it from here. But after watching it for a long time, I didn't see anything wrong with the methods in the class library, Because I didn't encounter this situation when I used it before, So I don't think it may be a problem here. And the product I'm in charge of has gone through a lot of tests. It's definitely no problem, So I said let me see how you call it. I opened his code and took a look. There are no other problems on the whole, But there is a place that caught my attention. The instantiation of this class in the code is placed in the global scope, Because it is an cs project, doing so will cause the object to be referenced all the time, so it cannot be released even during garbage collection, and the com component called here will cause the word process to be unable to close, and colleagues use multithreading here, so when the program 1 runs, there will be a lot of word processes that cannot be closed. The object here is instantiated into the threaded method, so that after the method is executed, the objects in the heap are in a non-referenced state, which is released during garbage collection, and the problem is solved naturally. In fact, it doesn't matter whether it is single-threaded or multi-threaded. It is mainly instantiated in the global scope, which leads to the object not being garbage collected. Therefore, when writing code, 1 must pay attention to the life cycle of the object.


Related articles: