Solidworks, отслеживание ошибки нарушения доступа к памяти на Isldworks.CloseDoc

У меня есть две разные функции внутри аддона, над которым я работал в C#. В последнее время (по-видимому) Solidworks терпит крах, когда он добирается до определенных частей этих двух функций (возможно, больше, но это единственные два, которые я нашел до сих пор.) В разделе debug обе функции дают мне "ошибку нарушения доступа к памяти". Эта ошибка возникает каждый раз в строке, где я закрываю активный документ, и происходит примерно в 95% случаев.

Это почти всегда с одной и той же стороны. Кажется, что он не зависит от времени выполнения или количества частей, которые были открыты и закрыты. Если я не закрою файлы, я, похоже, не получу ошибку. Но при запуске большой сборки это представляет свои собственные проблемы. Добавление в 1S ожидания перед закрытием, кажется, уменьшает частоту ошибки (как и в, Я иногда могу пройти через всю сборку без ошибки)

быстрое объяснение того, что функция, о которой я в первую очередь беспокоюсь, выполнение; он работает с верхнего уровня сборки вниз, распространяя пользовательские свойства из основной сборки и сборок в их дочерние элементы. Поэтому я постоянно открываю и закрываю различные файлы сборок и деталей.

приведенный ниже код был разделен почти до минимума, который реплицирует ошибку. Ошибка возникает в строке 59. Из того, что я видел в интернете до сих пор, кажется, что их трудно отследить. Любая помощь очень оцененный.

    public void propagateProps(bool overwrite)  
    {  
        List<string> assemblies = new List<string>();  
        string topAssem;  
        string compName = "";  
        int i = 0;  
        int j = 0;  
        int errors = 0, warnings = 0;  
        int partType = 1;  
        swModel = iSwApp.ActiveDoc;  
        if (swModel == null)  
        {  
            MessageBox.Show("No assembly document open. Please open an assembly and try again.", "Avengers Assemble Error");  
            return;  
        }  
        if (swModel.GetType() != 2)  
        {  
            MessageBox.Show("No assembly document open. Please open an assembly and try again.", "Avengers Assemble Error.");  
            return;  
        }  
        topAssem = swModel.GetPathName();  
        assemblies.Add(swModel.GetPathName());  
        swAssy = iSwApp.ActiveDoc;  
        while (i < assemblies.Count)  
        {  
            List<string> beenDone = new List<string>();  
            iSwApp.OpenDoc(assemblies[i], 2);  
            swModel = iSwApp.ActivateDoc(assemblies[i]);                  
            swAssy = iSwApp.ActiveDoc;  
            foreach (Component2 swComp in swAssy.GetComponents(true))  
            {  
                partType = 1;  
                compName = swComp.GetPathName();  
                if (compName.IndexOf(").SLD") > 0 || compName.IndexOf("REF") > 0)  
                {  
                    continue;  
                }  
                if (Path.GetExtension(compName).ToUpper() == ".SLDASM")  
                {  
                    partType = 2;  
                    assemblies.Add(compName);  
                }  
                iSwApp.OpenDoc(compName, partType);  
                swModel = iSwApp.ActivateDoc(compName);  
                if (swModel == null)  
                {  
                    continue;  
                }  


                #region things that might not be in  


            #endregion  


                boolstatus = swModel.Save3(5, errors, warnings);  
                System.Threading.Thread.Sleep(500);  
                iSwApp.CloseDoc(swModel.GetPathName());  
            swPart = null;  
            swModel = null;  
            }  
            ++i;  
            System.Threading.Thread.Sleep(500);  
        }  


        return;  
    }  

Update: после просмотра этого вопроса;что вызывает нарушение доступа к памяти? Я попытался возиться с некоторыми глобальными переменными, которые я использую в своих функциях, безрезультатно. Однако мне удалось обернуть мой основной код в другую логическую структуру для циклического прохождения частей, которые, похоже, избегают этой проблемы. Но я чувствую, что это в лучшем случае пластырь и хотел бы избежать этой проблемы в будущем.

1 ответов


вы пишете код на C# - если вы не работаете с PInvokes, небезопасными блоками или подобными, для вас должно быть невозможно вызвать исключения доступа к памяти. Единственный разумный ответ тогда заключается в том, что SolidWorks имеет ошибку, которая либо приводит к сбою с учетом разумных входных данных, либо приводит к сбою, потому что она не проверяет необоснованные входные данные.

реальным исправлением было бы связаться с SolidWorks, чтобы они воспроизвели ошибку и исправили ее; за исключением этого, мы могли бы проанализировать ваш код для поиска взаимодействий, которые являются общими триггерами ошибок и ошибок. Например, они могут неправильно проверять все свои входные данные - вы можете предоставить недопустимые значения, которые они молча принимают; это не сломается намного позже.

если вы случайно передавали null, и они не проверяли, это может привести к нарушениям доступа к памяти, если они позже попытаются взять указатель из этого null. Если вы использовали ресурсы после их закрытия, а они не были проверяя для такого условия, они могут использовать устаревший указатель под капотом, также вызывая нарушение доступа к памяти.

в других ситуациях асинхронные операции могут быть причиной ошибки - если вы запустите некоторую асинхронную операцию, а затем закройте ресурс, привязанный к этой операции, когда эта операция позже будет выполняться в фоновом режиме, это может вызвать ошибки.

возможно, что способ использования возвращенных вам дескрипторов вызывает нарушения доступа к памяти. Я заметил, что вы не используете возвращаемое значение из OpenDoc, а вместо этого попытаться получить доступ к документам другими средствами. Что происходит, когда возвращаемое значение OpenDoc получает собранный мусор? Возможно, SolidWorks неправильно подсчитывает ссылки, и поэтому, когда возвращаемое значение GC'D, дескриптор под капотом закрыт и обнулен; однако другие операции по-прежнему ожидают, что он будет действительным и, таким образом, вызовет нарушения доступа к памяти.

также возможно, что вы используете устаревший API-если это так, возможно, вы используете код в SolidWorks, который имеет более высокую вероятность ошибки, поскольку он больше не тестируется или не поддерживается. Я заметил, что вы вызываете OpenDoc метод, который в их документации указан как устаревший. Вместо этого рекомендуется использовать такие методы, как OpenDoc6.

за пределами исправления реальной проблемы с API либо сломан, или не проверяя против сломанных входов достаточно хорошо, ваш единственный вариант - исследуйте эти источники общих проблем API.