0

I copied and implemented the code below. The code does what it is supposed to do. My problem is that it's leaking memory. It seems that I've isolated it down to a problem with the Thread allocation in each of the methods, but I do not understand why it is leaking memory. I'm calling ContainsText from within a loop, waiting for certain text to hit the clipboard. But I need to fix the memory leak, can anyone explain why the Thread allocation is leaking, and how to fix it?

public class ClipboardAsync
{
    private string _GetText;

    private void _thGetText(object format)
    {
        try
        {
            if (format == null)
            {
                _GetText = Clipboard.GetText();
            }
            else
            {
                _GetText = Clipboard.GetText((TextDataFormat)format);
            }
        }
        catch (Exception ex)
        {
            //Throw ex
            _GetText = string.Empty;
        }
    }

    public string GetText()
    {
        string getText = string.Empty;
        ClipboardAsync instance = new ClipboardAsync();
        Thread staThread = new Thread(instance._thGetText);
        staThread.SetApartmentState(ApartmentState.STA);
        staThread.Start();
        staThread.Join();
        getText = instance._GetText;
        return getText;
    }

    public string GetText(TextDataFormat format)
    {
        string getText = string.Empty;
        ClipboardAsync instance = new ClipboardAsync();
        Thread staThread = new Thread(instance._thGetText);
        staThread.SetApartmentState(ApartmentState.STA);
        staThread.Start(format);
        staThread.Join();
        getText = instance._GetText;
        return getText;
    }

    private bool _ContainsText;

    private void _thContainsText(object format)
    {
        try
        {
            if (format == null)
            {
                _ContainsText = Clipboard.ContainsText();
            }
            else
            {
                _ContainsText = Clipboard.ContainsText((TextDataFormat)format);
            }
        }
        catch (Exception ex)
        {
            //Throw ex
            _ContainsText = false;
        }
    }

    public bool ContainsText()
    {
        bool containsText = false;
        ClipboardAsync instance = new ClipboardAsync();
        Thread staThread = new Thread(instance._thContainsText);
        staThread.SetApartmentState(ApartmentState.STA);
        staThread.Start();
        staThread.Join();
        containsText = instance._ContainsText;
        return containsText;
    }

    public bool ContainsText(object format)
    {
        bool containsText = false;
        ClipboardAsync instance = new ClipboardAsync();
        Thread staThread = new Thread(instance._thContainsText);
        staThread.SetApartmentState(ApartmentState.STA);
        staThread.Start(format);
        staThread.Join();
        containsText = instance._ContainsText;
        return containsText;
    }

    private bool _ContainsFileDropList;

    private void _thContainsFileDropList(object format)
    {
        try
        {
            _ContainsFileDropList = Clipboard.ContainsFileDropList();
        }
        catch (Exception ex)
        {
            //Throw ex
            _ContainsFileDropList = false;
        }
    }

    public bool ContainsFileDropList()
    {
        ClipboardAsync instance = new ClipboardAsync();
        Thread staThread = new Thread(instance._thContainsFileDropList);
        staThread.SetApartmentState(ApartmentState.STA);
        staThread.Start();
        staThread.Join();
        return instance._ContainsFileDropList;
    }

    private System.Collections.Specialized.StringCollection _GetFileDropList;

    private void _thGetFileDropList()
    {
        try
        {
            _GetFileDropList = Clipboard.GetFileDropList();
        }
        catch (Exception ex)
        {
            //Throw ex
            _GetFileDropList = null;
        }
    }

    public System.Collections.Specialized.StringCollection GetFileDropList()
    {
        ClipboardAsync instance = new ClipboardAsync();
        Thread staThread = new Thread(instance._thGetFileDropList);
        staThread.SetApartmentState(ApartmentState.STA);
        staThread.Start();
        staThread.Join();
        return instance._GetFileDropList;
    }
}
Kevin
  • 1
  • 1
  • 1
  • 1
    Don't keep making new threads, reuse them. http://stackoverflow.com/q/4528261/103167 – Ben Voigt Feb 03 '17 at 20:50
  • C# is a managed language, so it never actually leaks memory on managed types. I imagine it's just suboptimal code for the garbage collector. – PC Luddite Feb 03 '17 at 21:05
  • how did you detect the leak? use memory profiling and see if you are really building up generation 2 / keepalive references that hinder GC, or if it is just awaiting routine GC.Collect – Cee McSharpface Feb 04 '17 at 00:13
  • I just ran it in Task Manager and saw the memory size increasing but the Thread count never increased. I found this strange. I figured it was leaking threads so I expected to see the Thread count increase. I ran it overnight and the size went from 11k to 150k. – Kevin Feb 06 '17 at 12:59
  • @Kevin, that behavior may be normal, the garbage collector may expand the heap size in order to reduce the amount of collections it needs to perform. – BlueStrat Apr 17 '17 at 23:10

0 Answers0