Ausführen eines ‚GC.Collect‘ behebt meinen Absturz, aber ich verstehe nicht, warum

StackOverflow https://stackoverflow.com/questions/995294

  •  13-09-2019
  •  | 
  •  

Frage

Ich habe dieses Stück Code (aus dem Nokia PC Connectivity 3.2 Beispielcode in 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);

Wenn ich GC.Collect() zu Beginn dieses laufen, dann erhalte ich keine AccessViolationException. Aber ich mag diese Funktion nicht verlangsamen, wenn nicht erforderlich. Ich habe GC.Keepalive an verschiedenen Orten versucht setzen, aber ohne Erfolg.

CA_FOLDER_INFO ist definiert als:

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

Ich weiß nicht, in diesem Fall benötigen Sie eine der Saiten, und ihre Definitionen zu IntPtr Veränderung scheint die Ausnahme zu machen geht weg.

Was ist hier los ist, und was ist der richtige Weg, um die Ausnahme zu verhindern?

War es hilfreich?

Lösung

Ihr Problem ist, dass Sie Marshal.StructureToPtr wahr vorbei sind, so dass es die beiden String-Zeiger zu befreien versucht (die manchmal sind ungültig). Sie müssen in diesem Fall falsch passieren, da Sie nur, dass der Speicher auf dem Heap zugeordnet. (Das heißt, es gibt nichts, was es zu befreien).

Andere Tipps

Sind Sie sicher, Marshal.SizeOf (bufItem) und Marshal.SizeOf (Folder) gleich sind?

Und vielleicht die Tatsache, dass Sie nicht die Saiten initialisiert wird? Da Sie sagen, dass Sie nicht den Fehler, wenn sie IntPtr (welche standardmäßig IntPtr.Zero) sind, würde ich versuchen, sie beide zu leere Saiten einstellen, bevor Sie das Pufferfeld versuchen Marshalling.

[Bearbeiten]

Vielleicht sollten Sie versuchen, den Puffer Griff Pinning, und dass an der Struktur Marshalling, anstatt vis kehrt. So etwas wie folgt aus:

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

Mit dem festen Schlüsselwort einen Zeiger auf Ihren ursprünglichen folderInfo zu erhalten.

Es könnte sein, dass nicht verwalteten Ressourcen nicht durch etwas freigesetzt werden. Überprüfen Sie, ob alles, was Sie verwenden implementiert IDisposable und wenn ja, wickeln sie es in einem using { } Block.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top