所以我收到了一个看起来好像是垃圾回收已损坏的错误:
Application Crashes With "Internal Error In The .NET Runtime"
完整错误是:
由于.NET运行时IP 71C571C8(71B20000)出现内部错误,退出代码80131506,该过程被终止。
它正在运行:
框架版本:v4.0.30319
当重复运行此功能时,这种情况会不一致地出现:
public static int GetMdiTitledChildWindows(IntPtr parentWindow)
{
IntPtr mdiClient = FindWindowEx(parentWindow, IntPtr.Zero, MdiClient, "");
List<IntPtr> handles = new List<IntPtr>();
EnumChildWindows(mdiClient, (hwnd, param) =>
{
handles.Add(hwnd);
return true;
}, IntPtr.Zero);
int counter = 0;
foreach (IntPtr handle in handles)
{
StringBuilder builder = new StringBuilder();
GetWindowText(handle, builder, GetWindowTextLength(handle)+1);
if (builder.Length > 0)
{
counter++;
}
}
return counter;
}
FindWindowEx()
,EnumChildWindows()
和GetWindowText()
都是p / invoke签名,其定义与此类似:
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool EnumChildWindows(IntPtr hwndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam);
该错误似乎仅在我多次运行该方法之后才会发生,但是,这种情况并不会一直发生。有时候它有用,有时候却没有。
关于如何解决此问题的任何建议?
答案 0 :(得分:3)
所以我在Discord的慷慨捐助者的帮助下解决了我的问题。
问题是我正在将Lamda
作为委托传递给p / invoke:
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool EnumChildWindows(IntPtr hwndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam);
因此,每次unmanaged
WinAPI
回调回我的委托人时,GC
都有机会运行,如果这样做,它将收集我的lamda导致崩溃。这不一定会发生,因此为什么我的方法在大多数情况下都有效并且崩溃不一致。
解决方案是添加对lamda的引用,以防止GC收集它(尽管我是全猪,由于皮带和花括号而使其成为局部函数):
public static int GetMdiTitledChildWindows(IntPtr parentWindow)
{
IntPtr mdiClient = FindWindowEx(parentWindow, IntPtr.Zero, MdiClient, "");
List<IntPtr> handles = new List<IntPtr>();
bool addToList(IntPtr hwnd, IntPtr param)
{
handles.Add(hwnd);
return true;
}
EnumWindowsProc gcHolder = addToList;
EnumChildWindows(mdiClient, gcHolder, IntPtr.Zero);
int counter = 0;
foreach (IntPtr handle in handles)
{
int textLength = GetWindowTextLength(handle) + 1;
StringBuilder builder = new StringBuilder(textLength);
GetWindowText(handle, builder, textLength);
if (builder.Length > 0)
{
counter++;
}
}
return counter;
}
该应用程序现在可以正常运行了。