开发者

Why shouldn't I use GC.Collect()

开发者 https://www.devze.com 2023-02-27 15:23 出处:网络
I am developing an application where I work with CertAdm.dll to make connections to a Certificate Authorit开发者_如何学运维y. Sometimes I get the error \"An attempt was made to open a Certification Au

I am developing an application where I work with CertAdm.dll to make connections to a Certificate Authorit开发者_如何学运维y. Sometimes I get the error "An attempt was made to open a Certification Authority database session, but there are already too many active sessions. The server may need to be configured to allow additional sessions."

If I configure my connection like the code below, I dont get the error and all works fine.

CERTADMINLib.ICertView2 cv2 = new CERTADMINLib.CCertViewClass();

try
{
    cv2.OpenConnection(srtCAConfig);
}
catch
{
    GC.Collect();
    GC.WaitForPendingFinalizers();
    cv2.OpenConnection(srtCAConfig);
}

Now what I am wondering about is that I have read a lot where people say you shouldn't use GC.Collect(). Why shouldn't I? It solves my problem?

All help is very appreciated.


Short answer: Garbage collection becomes less efficient the more you do it.

Waiting for pending finalisers is also undesirable. You are holding up your code to wait for an unknown number of objects to perform cleanup operations that could take an unknown amount of time. If you fixed the underlying problem, there'd be no need to wait for any of them.

As for the underlying problem, when an object owns some external (scarce) resource, it's important that when you're done with it, you call the appropriate method to release the resource. Often that's a method called Dispose(), CloseConnection() or something similar.

however, this is a COM interop object and all MSDN says is

To close the connection, call the Release function (C++) or set the object to Nothing (Visual Basic).

In .NET, the equivalent is to call System.Runtime.InteropServices.Marshal.ReleaseComObject(cv2). Once you've done that, the object referred to by cv2 is invalid, so don't call it again.


Maybe it solves your problem because of incorrect work with connections in your class.

Try to examine all about connections in your app, see where they are opened and where closed - I think that you don't close connections / don't clear resources that are used by your connections.


I think you are not closing the connections after opening them and finally it exceeds the maximum number of connections that can be open at a time. When you give GC.Collect(), each and every time the connection object is forcefully collected , because of which you cannot reuse the already open connection.

0

精彩评论

暂无评论...
验证码 换一张
取 消