'gc.collect'를 실행하면 충돌이 해결되지만 그 이유를 이해하지 못합니다.
문제
이 코드가 있습니다 (Nokia PC Connectivity 3.2 예제 코드, C#) :
DAContentAccessDefinitions.CA_FOLDER_INFO folderInfo =
new DAContentAccessDefinitions.CA_FOLDER_INFO();
folderInfo.iSize = Marshal.SizeOf(folderInfo); //(32)
IntPtr bufItem = Marshal.AllocHGlobal(folderInfo.iSize);
//I often get a AccessViolationException on the following line
Marshal.StructureToPtr(folderInfo, bufItem, true);
내가 달리면 GC.Collect()
이것의 시작시, 나는 얻지 못한다 AccessViolationException
. 그러나 필요하지 않으면이 기능을 늦추고 싶지 않습니다. 나는 퍼팅을 시도했다 GC.Keepalive
여러 곳에서는 성공하지 못했습니다.
CA_FOLDER_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
예외가 사라지는 것 같습니다.
여기서 무슨 일이 일어나고 있으며 예외를 방지하는 올바른 방법은 무엇입니까?
해결책
당신의 문제는 당신이 마샬.structuretoptr로 충실하기 때문에 두 개의 문자열 포인터 (때로는 유효하지 않음)를 제거하려고 시도한다는 것입니다. 힙에 해당 메모리를 할당 했으므로이 인스턴스에서 False를 전달해야합니다. (즉, 거기에서 자유롭게 할 수있는 것은 없습니다).
다른 팁
Marshal.sizeof (bufitem) 및 Marshal.sizeof (folderinfo)가 동일합니까?
그리고 당신이 현을 초기화하지 않았다는 사실일까요? intptr (intptr.zero의 기본값) 일 때 오류가 발생하지 않는다고 말하면 버퍼 항목을 마샬링하기 전에 비어있는 문자열로 둘 다 설정하려고합니다.
편집하다
어쩌면 버퍼 핸들을 고정시키고 Versa 대신 대신 구조물에 마샬링해야 할 수도 있습니다. 이 같은:
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
고정 키워드를 사용하여 원본에 대한 포인터를 얻으십시오. folderInfo
.
관리되지 않는 자원이 무언가에 의해 출시되지 않을 수 있습니다. 구현을 사용하는 것이 있는지 확인하십시오 idisposable 그렇다면 a로 싸십시오 using { }
차단하다.