تشغيل "gc.collect" إصلاح تحطم بلدي، لكنني لا أفهم لماذا

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

  •  13-09-2019
  •  | 
  •  

سؤال

لدي هذه القطعة من الكود (من رمز اتصال 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 { } منع.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top