C# 这个来自堆栈溢出的代码示例泄漏内存,有人能解释原因并提供修复方案吗?

C# 这个来自堆栈溢出的代码示例泄漏内存,有人能解释原因并提供修复方案吗?,c#,memory,memory-leaks,clipboard,C#,Memory,Memory Leaks,Clipboard,我复制并实现了下面的代码。代码执行它应该执行的操作。我的问题是它正在泄漏内存。似乎我已经把它归结为每个方法中的线程分配问题,但我不理解它为什么会泄漏内存。我在循环中调用ContainsText,等待某些文本进入剪贴板。但是我需要修复内存泄漏,有人能解释为什么线程分配会泄漏,以及如何修复它吗 public class ClipboardAsync { private string _GetText; private void _thGetText(object format)

我复制并实现了下面的代码。代码执行它应该执行的操作。我的问题是它正在泄漏内存。似乎我已经把它归结为每个方法中的线程分配问题,但我不理解它为什么会泄漏内存。我在循环中调用ContainsText,等待某些文本进入剪贴板。但是我需要修复内存泄漏,有人能解释为什么线程分配会泄漏,以及如何修复它吗

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;
    }
}

不要一直制造新线程,重新使用它们。C#是一种托管语言,因此它实际上从不泄漏托管类型的内存。我想这只是垃圾收集器的次优代码。你是如何检测泄漏的?使用内存评测,看看您是否真的在构建阻碍GC的第2代/keepalive引用,或者它只是在等待例程GC.CollectI。我刚刚在任务管理器中运行了它,看到内存大小在增加,但线程数从未增加。我觉得这很奇怪。我估计它正在泄漏线程,所以我希望看到线程数增加。我一夜之间运行了它,大小从11k变为150k。@Kevin,这种行为可能很正常,垃圾收集器可能会扩展堆大小以减少需要执行的收集量。