login about faq

I have a server application that sends files using Chilkat.Socket.SendBytesAsync(byte[]). The files are about 50MB in size on average.

When I call Task.Run() on the Task object returned from Chilkat.Socket.SendBytesAsync(byte[]), I see memory usage spike about 50MB as expected while the task is running. After the Task is running, I add the Task object to a ConcurrentDictionary collection along with the Socket and in another thread I check the progress of the running Tasks regularly. When each Task is complete, I dispose of the Task object and the Socket object that the Task used.

Unfortunately, memory usage never drops after disposing of the Task and the Socket. Every 50MB file I send yields another 50MB of memory usage. If I use the exact same code but call the synchronous method SendBytes, all memory is freed up after SendBytes is complete and I dispose of the Socket object, so it appears to have something to do with the Asynchronous call.

Following are some of my code snippets.

Here is where I am asynchronously sending the byte[]

Chilkat.Task t = tcpSocket.SendBytesAsync(bytesToSend);   
if (!t.Run())
    {
        LogError("failed to send file: " + tcpSocket.LastErrorText);
        return null;
    }
_remoteClients_DownloadsInProgress.TryAdd(tcpSocket, t); //add Task and Socket to a collection

Here, on another thread, is where I check the Task progress and dispose of it if it is completed:

            foreach(RemoteClient rc in _remoteClients_DownloadsInProgress.Keys)
        {
            _remoteClients_DownloadsInProgress.TryGetValue(tcpSocket, out taskout);

            if ((taskout.StatusInt == 7 && taskout.Finished && taskout.TaskSuccess) )
            {
                //close the socket
                LogDebugInfo("Task Complete!");
                try
                {
                    _remoteClients_DownloadsInProgress.TryRemove(tcpSocket, out taskout);
                    tcpSocket.Close(500);
                    taskout.Dispose();
                    GC.Collect();
                    GC.WaitForPendingFinalizers();
                }
                catch (Exception ex)
                {

                    LogException(ex);
                }

            }
        }

I am using version 9.5.0.58 of the ChilkatDotNet4.dll

Is there anything in particular I need to do to free up the memory used by the Chilkat dll when calling SendBytesAsync()?

Thanks

asked Nov 18 at 11:45

Moraeulf's gravatar image

Moraeulf
31


I found the cause of the problem. It's a problem specific to passing byte arrays to an Async method in .NET. This problem should be present in all async methods that have byte array arguments (but only for .NET). I should have it fixed for later today, and I'll post a v9.5.0.65 pre-release -- which should be stable because nothing much as occurred yet since v9.5.0.64 (see http://cknotes.com/v9-5-0-65-pre-release-notes/ )

link

answered Nov 18 at 12:55

chilkat's gravatar image

chilkat ♦♦
11.8k316358420

Wow thanks for the quick turnaround! Much appreciated!

(Nov 18 at 13:46) Moraeulf

Thanks.. I'll have a look..

link

answered Nov 18 at 11:49

chilkat's gravatar image

chilkat ♦♦
11.8k316358420

Thank you. Right now i've decided to just stick with using the Synchronous SendBytes() and just calling that on multiple caller threads to service concurrent download requests and it appears to be working fine that way - memory usage always drops back to normal after the downloads are serviced.

(Nov 18 at 12:50) Moraeulf

Here's a new build that should fix it:

http://chilkatdownload.com/prerelease/chilkatdotnet4-9.5.0-win32.zip
http://chilkatdownload.com/prerelease/chilkatdotnet4-9.5.0-x64.zip

(I haven't tested it yet, but it should work..)

Also, the following Socket methods were added:

  • SendBd
  • SendSb
  • ReceiveBd
  • ReceiveBdN
  • ReceiveSb

These are methods for sending/receiving directly from BinData and StringBuilder objects. See the online reference documentation at https://www.chilkatsoft.com/refdoc/csSocketRef.html

If the 50MB you're sending is data from a file, then you could instead instantiate a Chilkat.BinData object, load it with the file data, and then send it by calling SendBd. This is far better than calling SendBytes. The reason is that w/ SendBytes, the byte array must be marshaled from managed to unmanaged internally. This would cause a temporary spike in memory usage, and of course takes some time. If passing a BinData, then the data stays in unmanaged memory, and there's no memory usage spike, and no marshaling, so it should be faster.

But even if you still use SendBytes, the leak should be fixed.. (I'll verify by testing soon..)

link

answered Nov 18 at 16:33

chilkat's gravatar image

chilkat ♦♦
11.8k316358420

Excellent thanks. I'll give this a shot and try using the BinData object instead of a byte[] and post my results here.

(Nov 18 at 17:23) Moraeulf
Your answer
toggle preview

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Markdown Basics

  • *italic* or __italic__
  • **bold** or __bold__
  • link:[text](http://url.com/ "title")
  • image?![alt text](/path/img.jpg "title")
  • numbered list: 1. Foo 2. Bar
  • to add a line break simply add two spaces to where you would like the new line to be.
  • basic HTML tags are also supported

Tags:

×60
×21

Asked: Nov 18 at 11:45

Seen: 305 times

Last updated: Nov 18 at 17:23

powered by OSQA