代码之家  ›  专栏  ›  技术社区  ›  ScottishTapWater

.NET运行时错误80131506-将Lambda传递给本机函数

  •  3
  • ScottishTapWater  · 技术社区  · 6 年前

    Application Crashes With "Internal Error In The .NET Runtime"

    完全错误是:

    由于.NET运行时在IP 71C571C8(71B20000)处出现内部错误,进程已终止,退出代码为80131506。

    正在运行:

    重复运行此函数时会出现不一致的情况:

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

    关于如何解决这个问题有什么建议吗?

    1 回复  |  直到 6 年前
        1
  •  6
  •   ScottishTapWater    6 年前

    所以我在一位慷慨的恩人的帮助下解决了我的问题。

    问题是我路过一个 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的引用,以防止GC收集它(尽管我全力以赴地将它作为本地函数,因为belt和braces):

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

    应用程序现在可以正常工作了。