C# 运行';GC.Collect';修复了我的崩溃,但我没有';我不明白为什么

C# 运行';GC.Collect';修复了我的崩溃,但我没有';我不明白为什么,c#,unmanaged,nokia,C#,Unmanaged,Nokia,我有这段代码(来自诺基亚PC connectivity 3.2示例代码,用C#表示): 如果在开始时运行GC.Collect(),则不会得到AccessViolationException。但除非必要,否则我不想减慢此功能。我曾尝试在不同的地方放置GC.Keepalive,但没有成功 CA\u FOLDER\u INFO定义为: [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)] public struct

我有这段代码(来自诺基亚PC connectivity 3.2示例代码,用C#表示):

如果在开始时运行
GC.Collect()
,则不会得到
AccessViolationException
。但除非必要,否则我不想减慢此功能。我曾尝试在不同的地方放置
GC.Keepalive
,但没有成功

CA\u FOLDER\u INFO
定义为:

    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
    public struct CA_FOLDER_INFO
    {
        public int iSize;
        public int iFolderId;
        public int iOptions;
        public string pstrName;
        public string pstrPath;
        public int iSubFolderCount;
        public IntPtr pSubFolders;
        public IntPtr pParent;
    }
在本例中,我不需要这两个字符串中的任何一个,将它们的定义更改为
IntPtr
似乎可以消除异常


这里发生了什么,防止异常的正确方法是什么?

使用fixed关键字获取指向原始
folderInfo
的指针使用fixed关键字获取指向原始
folderInfo
的指针可能是某些东西没有释放非托管资源。检查是否有任何您正在使用的实现,如果是,请使用{}块将其包装在
中。

可能是某些东西没有释放非托管资源。检查您正在使用的工具是否有任何内容,如果有,请使用{}
块将其包装在
中。

您确定Marshal.Sizeof(bufItem)和Marshal.Sizeof(folderInfo)是相同的吗

还有,可能是因为你没有初始化字符串?因为您说当它们是IntPtr(默认为IntPtr.Zero)时不会出现错误,所以在尝试封送缓冲区项之前,我会尝试将它们都设置为空字符串

[编辑]

也许您应该尝试固定缓冲区句柄,并将其封送到结构,而不是相反。大概是这样的:

DAContentAccessDefinitions.CA_FOLDER_INFO folderInfo;

GCHandle pinnedHandle = GCHandle.Alloc(buffItem, GCHandleType.Pinned);
folderInfo = (DAContentAccessDefinitions.CA_FOLDER_INFO)Marshal.PtrToStructure(pin.AddrOfPinnedObject(), typeof(DAContentAccessDefinitions.CA_FOLDER_INFO));
pin.Free();

//folderInfo should contain the data from buffItem

您确定Marshal.Sizeof(bufItem)和Marshal.Sizeof(folderInfo)是相同的吗

还有,可能是因为你没有初始化字符串?因为您说当它们是IntPtr(默认为IntPtr.Zero)时不会出现错误,所以在尝试封送缓冲区项之前,我会尝试将它们都设置为空字符串

[编辑]

也许您应该尝试固定缓冲区句柄,并将其封送到结构,而不是相反。大概是这样的:

DAContentAccessDefinitions.CA_FOLDER_INFO folderInfo;

GCHandle pinnedHandle = GCHandle.Alloc(buffItem, GCHandleType.Pinned);
folderInfo = (DAContentAccessDefinitions.CA_FOLDER_INFO)Marshal.PtrToStructure(pin.AddrOfPinnedObject(), typeof(DAContentAccessDefinitions.CA_FOLDER_INFO));
pin.Free();

//folderInfo should contain the data from buffItem

您的问题是将true传递给Marshal.StructureToPtr,因此它试图释放两个字符串指针(这两个指针有时无效)。在这个实例中,您需要传递false,因为您刚刚在堆上分配了那个内存。(也就是说,那里没有任何可释放的内容)。

您的问题是将true传递给Marshal.StructureToPtr,因此它尝试释放两个字符串指针(有时无效)。在这个实例中,您需要传递false,因为您刚刚在堆上分配了那个内存。(也就是说,没有什么可以释放的)。

不要忘记在完成bufItem后调用Marshal.FreeHGlobal的try finally中包装它。不要忘记在完成bufItem后调用Marshal.FreeHGlobal的try finally中包装它。将两个字符串字段设置为“”或String.Empty不会使AccessViolationException消失…将两个字符串字段设置为“”或String.Empty不会使AccessViolationException消失…谢谢,这似乎有效,这是我理解的解释。谢谢,这似乎有效,这是我理解的解释。