تشغيل "gc.collect" إصلاح تحطم بلدي، لكنني لا أفهم لماذا
سؤال
لدي هذه القطعة من الكود (من رمز اتصال Nokia PC 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
يبدو أنها تجعل الاستثناء يذهب بعيدا.
ما الذي يحدث هنا، وما هي الطريقة الصحيحة لمنع الاستثناء؟
المحلول
مشكلتك هي أنك تمر TRUE TRUE TO MARSHAL.SERTURETOPTR بحيث تحاول تحرير مؤشرات السلسلة (التي هي في بعض الأحيان غير صالحة). تحتاج إلى تمرير خطأ في هذه الحالة لأنك تخصيص هذه الذاكرة على الكومة. (أي لا يوجد شيء مجانا هناك).
نصائح أخرى
هل أنت متأكد من 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
.
قد يكون الموارد غير المدارة لا يتم إصدارها بشيء ما. تحقق لمعرفة ما إذا كان أي شيء تستخدمه ينفط انهيار وإذا كان الأمر كذلك، لفه في using { }
منع.