2016-05-31 12 views
9

Ho due funzioni diverse all'interno di un addon su cui sto lavorando in C#. Di recente (apparentemente) SolidWorks si è arrestato in modo anomalo quando ha raggiunto alcune parti di queste due funzioni (forse di più, ma sono le uniche due in cui ho trovato che si verificano fino ad ora.) Sotto debug, entrambe le funzioni mi danno una "violazione dell'accesso alla memoria" Errore". Questo errore si verifica, ogni volta, sulla riga in cui sto chiudendo il documento attivo e si verifica circa il 95% delle volte.SolidWorks, rintracciare un errore di violazione di accesso alla memoria su Isldworks.CloseDoc

È quasi sempre sulla stessa parte. Sembra essere indipendente dal tempo di esecuzione o dal numero di parti che sono state aperte e chiuse. Se non chiudo i file, non riesco a ottenere l'errore. Ma quando si esegue un assembly di grandi dimensioni, questo presenta i propri problemi. Aggiungere 1 in attesa prima della chiusura sembra ridurre la frequenza dell'errore (Come in, posso occasionalmente attraversare l'intero assembly senza l'errore)

Una rapida spiegazione di ciò che la funzione che sono principalmente preoccupata sta facendo ; Funziona dal livello più alto di un assembly verso il basso, propagando le proprietà personalizzate dall'assieme principale e dai sottoassiemi, ai propri figli. Quindi sto costantemente aprendo e chiudendo diversi file di assemblaggio e di parti.

Il codice riportato di seguito è stato ridotto al minimo indispensabile per replicare l'errore. L'errore si verifica sulla linea 59. Da quello che ho visto finora online, sembra che sia difficile rintracciarlo. Qualsiasi aiuto è molto apprezzato.

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

Aggiornamento: Dopo aver visto questa domanda; What's causing the memory access violation? Ho provato a modificare alcune variabili globali che uso nelle mie funzioni senza alcun effetto. Tuttavia, sono riuscito a racchiudere il mio codice essenziale in una struttura logica diversa per eseguire il ciclo di parti che sembra evitare questo problema. Ma credo che questo sia un cerotto nel migliore dei casi e vorrei poter evitare questo problema in futuro.

+0

Nessuno ha alcun input su questo? – Nick

+1

Stai scrivendo il codice in C# - a meno che tu non stia lavorando con PInvokes, blocchi non sicuri o simili, dovrebbe essere impossibile per te causare delle eccezioni di accesso alla memoria. L'unica risposta ragionevole è che SolidWorks ha un bug che causa l'arresto anomalo di input ragionevoli o che causa un arresto anomalo perché non convalida gli input irragionevoli. Stai passando null ovunque? Stai tentando di utilizzare oggetti dopo che sono stati chiusi? Stai usando operazioni asincrone? Stai provvedendo a qualche gancio? – antiduh

+0

[OpenDoc] (http://help.solidworks.com/2012/English/api/sldworksapi/SolidWorks.Interop.sldworks~SolidWorks.Interop.sldworks.ISldWorks~OpenDoc.html) sembra essere deprecato. Qualche ragione per cui non stai usando i metodi più recenti? Perché non usi il valore restituito da OpenDoc? – antiduh

risposta

4

Si sta scrivendo il codice in C# - a meno che non si stia lavorando con PInvokes, blocchi non sicuri o simili, dovrebbe essere impossibile per te causare eccezioni di accesso alla memoria. L'unica risposta ragionevole è che SolidWorks ha un bug che causa l'arresto anomalo di input ragionevoli o che causa un arresto anomalo perché non convalida gli input irragionevoli.

La vera soluzione sarebbe contattare SolidWorks per far sì che riproducano il bug e lo risolvano; salvo ciò, potremmo analizzare il vostro codice per cercare interazioni che sono comuni trigger di bug e guasti. Ad esempio, potrebbero non convalidare correttamente tutti i loro input: potresti fornire valori non validi che accettano in silenzio; non si rompe fino a molto più tardi.

Se si passa accidentalmente a null e non si verificava, ciò potrebbe causare violazioni di accesso alla memoria se in seguito si tenta di prelevare un puntatore da tale valore nullo. Se stavi usando le risorse dopo che sono state chiuse, e non stavano convalidando per una tale condizione, potrebbero usare un puntatore non aggiornato sotto il cofano, causando anche una violazione di accesso alla memoria.

In altre situazioni, le operazioni asincrone possono causare l'errore: se si avvia un'operazione asincrona e quindi si chiude la risorsa legata a tale operazione, quando tale operazione procede successivamente in background, potrebbe causare errori.

È possibile che il modo in cui si utilizzano gli handle restituiti causi violazioni di accesso alla memoria. Ho notato che non si utilizza il valore restituito da OpenDoc e si tenta invece di accedere ai documenti con altri mezzi. Cosa succede quando il valore restituito da OpenDoc viene raccolto dalla garbage collection?Forse SolidWorks non è correttamente il conteggio dei riferimenti, e quindi quando il valore di ritorno è GC, la maniglia sotto il cappuccio viene chiusa e annullata; altre operazioni ancora si aspettano che sia valida e quindi causano violazioni di accesso alla memoria.

È anche possibile che si stia utilizzando un'API obsoleta. In tal caso, è possibile che si stia esercitando un codice in SolidWorks che ha una maggiore probabilità di essere bacato perché non viene più sottoposto a test o manutenzione. Ho notato che stai invocando il metodo OpenDoc, che la loro documentazione elenca come deprecato. Considera invece l'utilizzo dei metodi consigliati, ad esempio OpenDoc6.

Al di fuori di risolvere il problema reale con l'API sia in fase di interruzione, o non convalidare con ingressi interrotti abbastanza bene, l'unica opzione è quella di indagare su queste fonti di problemi API comuni.

+1

Come ho detto sopra, quali altri problemi potrebbero effettivamente causarlo, utilizzando la chiamata OpenDoc6 sembra aver risolto il problema sulla mia estremità. Grazie! – Nick

Problemi correlati