C# 使用Windows API EnumThreadWindows和列表的内存泄漏

C# 使用Windows API EnumThreadWindows和列表的内存泄漏,c#,windows,memory-leaks,.net-core,C#,Windows,Memory Leaks,.net Core,我使用EnumThreadWindows查找特定的windows句柄,并在找到它时更新一些列表,由于某些原因,当我在代理中使用列表时,我有内存泄漏 我检查了几次,当我对使用列表的行进行注释时,我的内存使用情况是稳定的 var result=newlist(); WindowsNativeAPI.EnumThreadWindows(thread.Id,(hWnd,lParam)=> { if(hWnd==IntPtr.Zero)返回true; result.Add(new SomeClass())

我使用EnumThreadWindows查找特定的windows句柄,并在找到它时更新一些列表,由于某些原因,当我在代理中使用列表时,我有内存泄漏

我检查了几次,当我对使用列表的行进行注释时,我的内存使用情况是稳定的

var result=newlist();
WindowsNativeAPI.EnumThreadWindows(thread.Id,(hWnd,lParam)=>
{
if(hWnd==IntPtr.Zero)返回true;
result.Add(new SomeClass());//如果我对此进行注释,则内存泄漏已修复
返回true;
},IntPtr.Zero);
每当我使用回调中的列表时,我都可以清楚地看到我的内存使用量增加,如果我不这样做,我的内存是稳定的。 另外值得一提的是,当我枚举进程线程时,这个函数被多次调用

编辑:我也注意到我对列表做什么并不重要,即使我 执行此操作而不是结果。添加:

Console.WriteLine(result.Count);
我仍然有内存泄漏

Edit2:我想我可以通过这样做来修复它:

var foundHandles=new List();
var gch=GCHandle.Alloc(foundHandles);
var lParam=GCHandle.ToIntPtr(gch);
然后将列表作为LPRAM传递给EnumThreadWindows,并在我使用的函数中:

var gcHandle=gcHandle.FromIntPtr(LPRAM);
var list=gcHandle.Target作为列表;
最终用途:

gch.Free();
我还将列表更改为IntPtr,并在稍后创建了一些类,但这没有帮助。 当我使用GCHandle通过我的列表时,我的记忆不再上升(我做了一个多小时的测试以确保) 但我还是不明白为什么像以前那样使用列表,我的程序的内存会随着时间的推移而增加而不减少,所以如果有人知道为什么,请解释:)

Edit3:我忘了提到我正在使用.NETCore3预览版6,我认为这不重要,因为我只使用WinAPI

编辑4:添加了一些基础: 当我在没有gc的情况下运行代码时,您可以尝试运行此代码。Alloc非托管内存永远不会被清除,即使我暂停程序并等待

public委托bool EnumWindowProc(IntPtr hWnd,IntPtr
[DllImport(“user32”,
[返回:Marshallas(非托管类型)。
公共静态外部bool EnumThreadWindows(int-threadId、EnumWindowProc回调、IntPtr
静态void Main(字符串[])
{
var a=真;
while(a)
{
foreach(var process in process.getprocesss())
{
foreach(ProcessThread-in-process.Threads)
{
var list=新列表();
EnumThreadWindows(thread.Id,(wnd,param)=>
{
列表。添加(wnd);
返回true;
},IntPtr.Zero);
thread.Dispose();
}
process.Dispose();
}
GC.Collect();
睡眠(1);
}
}
运行此代码时,我可以在DotMemory中看到:

使用GC.Alloc编写代码

var list=newlist();
var aloc=GCHandle.Alloc(列表);
var lParam=GCHandle.ToIntPtr(aloc);
EnumThreadWindows(thread.Id,(wnd,param)=>
{
var list1=GCHandle.fromintpr(param).Target作为列表;
列表1?添加(wnd);
返回true;
},lParam);
thread.Dispose();
aloc.Free();


我可能不懂一些基本的东西,但即使我现在在使用GC.Alloc时没有任何问题,我仍然想了解为什么会发生这种情况。谢谢

如果您创建一个静态(hWnd,lParam)=>{}方法?当您向列表中添加项目时,内存使用量增加并不是不正常的。如何确定内存正在泄漏?@JeroenHeier-我刚刚尝试过,但没有成功:(我也必须将列表更改为静态。这一切都不表示资源泄漏。您选择使用具有非确定性垃圾收集的编程语言。您不应该期望确定性垃圾收集。这可能仍然是资源泄漏,但目前的证据还不够。在尝试修复问题之前,请先确保存在该问题。到目前为止,没有令人信服的证据支持存在泄漏的假设。请提供证据。如果创建一个静态(hWnd,lParam)=>{}方法?当您向列表中添加项目时,内存使用量增加并不是不正常的。如何确定内存正在泄漏?@JeroenHeier-我刚刚尝试过,但没有成功:(我也必须将列表更改为静态。这一切都不表示资源泄漏。您选择使用具有非确定性垃圾收集的编程语言。您不应该期望确定性垃圾收集。这可能仍然是资源泄漏,但目前的证据还不够。在尝试修复问题之前,请先确保问题存在。到目前为止,没有令人信服的证据支持存在泄漏的假设。请提供证据。