Archived Forum Post

Index of archived forum posts

Question:

C# Http Multithread Disposal Deadlock

Aug 10 '14 at 09:20

Using Chilkat 9.5.0.41 for .NET 4.5 x86

I have a class that holds a global Chilkat.Http object. I load several of these classes as threads at any given time. All of these threads utilize proxies and often have slow or unpredictable connections. Each class initializes the Http object before the constructor when the global object is declared:

public Chilkat.Http http = new Http();

The Http workers generally perform QuickGetStr. However, sometimes I want to abort these threads. I noticed that the memory was lingering after aborting the threads, so I suspected that non-disposal could be the culprit. I used a memory profiler and it indicated that all of my Chilkat.Http objects are "Queued for finalization":

An instance was queued for finalization at the start of the snapshot and has not been finalized at the time the snapshot collection finished. This can indicate that too many instances are being finalized, that the finalizers take too long time to execute, or that a finalizer is stuck (e.g. a dead-lock). This issue can also occur if an instance is being re-registered for finalization without assigning a strong reference to it.

The profiler specifically points to the m_lockImpl variable:

alt text

I use the http object in several methods and I never know when the thread might be aborted, so using a Dispose() function seemed to make the most sense. Therefore I tried to implement IDisposable into my class and force the http objects to Dispose() when necessary:

protected void Dispose(bool disposing)
{
    if (disposing)
    {
        // Code to dispose the managed resources of the class
        http.CloseAllConnections();
        http.Dispose();
        //null delegates
        this._PostUpdate = null;
        this._PostUpdateWithType = null;
    }

    // Code to dispose the un-managed resources of the class

    disposed = true;
}

public void Dispose()
{
    Dispose(true);
    GC.SuppressFinalize(this);
}

~Thread()
{
    Dispose(false);
}

When I call dispose, the application deadlocks. Some of the threads will dispose while others enter the Dispose call and never return. I found that closing the connections first helped to alleviate this issue, but it still exists. How can I resolve this issue? Why is it deadlocking? Is there a better way to dispose of the http objects?


Answer

I purchased a license. I don't understand why I haven't received a response to this.

Just wanted to add that Http.CloseAllConnections() is also causing a deadlock.


Answer

Jordan, the Forum is a venue for users to help each other. It is not an official support channel. Chilkat does not necessarily recognize the identity of each poster, and must prioritize responses based on who is currently under paid support. When Chilkat does recognize the poster as someone with valid support, it is treated as an official support request.

The Chilkat .NET objects are thread-safe. This means that there can only be one method call (or property access) at a time for a given object instance. If two threads try to make method calls simultaneously on the same object instance, then the one that happens to be first gains access, and the other must wait until the 1st completes.

In your case, if one thread is waiting for the call to QuickGetStr to return, then another thread that tries to call CloseAllConnections, or Dispose, must wait until the QuickGetStr completes.

To properly abort a Chilkat method call (and this is standard across all Chilkat classes that involve TCP communications, or do anything else potentially time consuming), is to use the AbortCheck event callback. Set the HeartbeatMs property to a value for the frequency of AbortCheck callbacks desired. Then, when the operation is to be aborted, set the "abort" output arg in the AbortCheck callback to true (see the online reference documentation) and the method (QuickGetStr) will abort.