none
AccessViolationException RRS feed

  • Frage

  • Hallo,

     

    ich hab da mal 'ne Frage. Beim Starten einer WinForms-Anwendung öffne ich in form.Shown ein zweites Formular, welches nach einem Klick auf einen Button ein Object vom Typ WebResponse (ftpWebRequest.GetResponse()) zurückgeben soll. Die IP-Adresse (hab zum testen 1.1.1.1 gewählt) ist aber nicht erreichbar, was zu einer Ausnahme führt, die jedoch abgefangen wird. In Form.Shown tritt nun jedoch eine AccessViolation-Exception auf, bei der ich nicht weiß, woher die kommt. Ich male das nochmal in Pseudo-Code.

     

    Hauptformular:

    void Mainform.Shown(){

       frm2 frm=new frm2();

       try

          frm.showdialog()

       catch (exception ex){

          // hier hab ich nun die AccessViolationException

       }

       frm.dispose();

    }

    -------------------

    anderes Formular:

    void Buttonklick(){

       try

          list<string> lst=   [andere Assembly].ftp.getFilelist(); // <-- WebException, weil ziel nicht erreichbar

       catch (exception ex){

       }

    }

     

    Ich habe nun 2 Möglichkeiten, wie ich den Fehler umgehen kann:

    1. ich sperre das ftpWebRequest-Object

       lock (ftpwebRequest){

          ftpwebRequest.GetResponse()

       }

     

    oder 2. ich öffne das zweite Form nicht aus dem Kontext des Hauptformulars sondern lass die Drecksarbeit einen Backgroundworker erledigen

    void Mainform.Shown(){

       backgroundworker bgw=new Backgroundworker();

       bgw.doWork += GetFileList;

       bgw.RunWorkerAsync();

    }

    void GetFilelist(){

       frm2 frm=new frm2();

       frm.showdialog()

       frm.dispose();

    }

     

    Beides funktioniert, aber ich würde gerne wissen, was die AccessViolationEception auslöst. Kann das was damit zu tun haben, dass die Ausnahme in frm.Shown() auftritt? Oder ist es kritisch, andere Fenster in Form.Shown zu öffnen?

    EDIT: tritt die WebException nicht auf, tritt auch die AccessViolationException nicht auf

    tia,

    Stefan

    Samstag, 30. Oktober 2010 12:13

Antworten

  • Hallo Stefan,

    Irgendwo interagiert Dein Code vermutlich mit nicht verwaltetem Code (ActiveX-Drittherstellerkomponente?), sonst würdest Du nur in den seltesten Fällen eine AccessViolationException erhalten. Poste doch bitte ein Stacktrace, damit wir die Aufrufskette etwas besser verstehen.

    AccessViolationException-Klasse:
    http://msdn.microsoft.com/de-de/library/system.accessviolationexception(v=VS.100).aspx

    P.S. Reine Neugier: Wenn Du frm2 in Form.Load instanziierst, hast Du den gleichen Ausnahmefehler?

    Gruß
    Marcel

    • Als Antwort vorgeschlagen Frank Dzaebel Samstag, 30. Oktober 2010 20:46
    • Als Antwort markiert Stefan Simon Montag, 1. November 2010 09:56
    Samstag, 30. Oktober 2010 12:56
    Moderator
  • Hallo Stefan,

    Ja, Zugriffsverletzungen treten zuweilen non-deterministisch auf (oft z.B. wenn das ActiveX-Control oder eine Dependency Multithreading benutzt). Sie werden unter gewissen Voraussetzungen vom Betriebsystem erzeugt und lassen sich oft schwer über Testszenarien nachvollziehen. Es ist beinahe unmöglich zu sagen, was das ActiveX-Control wirklich macht, wenn man nicht den dazugehörigen Sourcecode hat (geht eigentlich nur über hard core debugging) und der Fehler nur dann und wann auftritt (z.B. bei sporadischen Racebedingungen). Der Dritthersteller-Code könnte Exceptions-Hooks installieren und vergessen diese zu deinstallieren, er könnte Memoryleaks verursachen, oder versuchen Nullzeiger zu dereferenzieren usw.

    Du könntest aber entweder einen UnhandledException-Handler einsetzen (u.U. nur bis .NET 4.0 und im Normalfall nur für Hauptthreadexceptions) oder die Drittherstellerkomponente in einem eigenen AppDomain isolieren, so dass diese beim Absturz nicht die ganze Anwendung mitreißt (passiert trotzdem, wenn die Drittherstellerkomponente oder eine der Abhängigkeiten den aktuellen Prozess insgesamt abbricht). Du könntest ebenfalls eine der verfügbaren Plugin-Technologien einsetzen, die gute Isolation unterstützt, z.B. MAF. Alles kein Pappenstiel.

    s.a. http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/b2cc18d6-e42f-4b36-8174-d65eaddecbb1

    Gruß
    Marcel

    • Als Antwort markiert Stefan Simon Dienstag, 2. November 2010 07:19
    Montag, 1. November 2010 12:58
    Moderator

Alle Antworten

  • Hallo Stefan,

    Irgendwo interagiert Dein Code vermutlich mit nicht verwaltetem Code (ActiveX-Drittherstellerkomponente?), sonst würdest Du nur in den seltesten Fällen eine AccessViolationException erhalten. Poste doch bitte ein Stacktrace, damit wir die Aufrufskette etwas besser verstehen.

    AccessViolationException-Klasse:
    http://msdn.microsoft.com/de-de/library/system.accessviolationexception(v=VS.100).aspx

    P.S. Reine Neugier: Wenn Du frm2 in Form.Load instanziierst, hast Du den gleichen Ausnahmefehler?

    Gruß
    Marcel

    • Als Antwort vorgeschlagen Frank Dzaebel Samstag, 30. Oktober 2010 20:46
    • Als Antwort markiert Stefan Simon Montag, 1. November 2010 09:56
    Samstag, 30. Oktober 2010 12:56
    Moderator
  • Hallo Marcel,

     

    der Tipp mit der ActiveX-Drittherstellerkomponente war ein Volltreffer, ich nutze das Mobotix-Control zur Anzeige des Livebildes von Netzwerkkameras. Ohne das Ding tritt der Fehler nicht auf.

     

    Danke und schönes Wochenende,

    Stefan

    Samstag, 30. Oktober 2010 19:06
  • Hab noch eine Frage dazu. Gibt es eine Möglichkeit, solche ActiveX-Controls zu testen? Solche Pannen bei Kunden würde ich in Zukunft gerne vermeiden...

     

    Stefan

    Montag, 1. November 2010 08:53
  • Hallo Stefan,

    ActiveX-Steuerelemente können aus verschiedensten Gründen fehlschlagen. Eines der häufigsten besteht darin, dass auf dem Zielsystem das ActiveX-Control gar nicht vorhanden/installiert ist. Du kannst in diesem Fall über einen Vortest ermitteln, ob alles in Ordnung ist, z.B.:

    try
    {
      Guid classID = new Guid("{8D52281D-565B-4bc9-B5CE-22760066E653}"); // CLSID des Controls
      Type type = Type.GetTypeFromCLSID(classID, true);
      object objectInstance = System.Activator.CreateInstance(type);
      System.Runtime.InteropServices.Marshal.ReleaseComObject(objectInstance);
    }
    catch
    { 
      // Fehlerbehandlung
    }
    
    

    [Bitte markiere die Beiträge die Du als gültige Antwort betrachtest, bzw. jene die Dir weitergeholfen haben. Das ist ein wichtiger Hinweis für andere Entwickler, die sich evtl. zukünftig mit demselben Problem herumschlagen.]

    Gruß
    Marcel

    Montag, 1. November 2010 09:33
    Moderator
  • Hallo Marcel,

    das ActiveX-Control ist auf dem Zielsystem vorhanden und tut eigentlich auch das, was es soll. Es gibt vom Hersteller eine neuere Version, mit der sich der Fehler nicht reproduzieren lässt. Die Frage ist, greift das Control auf den Speicher meiner Anwendung zu oder umgekehrt und lassen sich solche Fehler irgendwie testen? Ich meine, wie kann ich sicher sein, das die AccessViolationException nicht an anderer Stelle wieder auftritt? Ich nutze das Control in meiner Anwendung seit über 2 Jahren und jetzt erst trat der Fehler in Erscheinung, nachdem eine WebException aufgetreten ist, die dazu noch abgefangen wurde. Das ist reiner Zufall gewesen, ein Testszenario wär mir lieber. Oder eine Möglichkeit, das Control irgendwie zu kapseln, damit dort auftretende Fehler nicht gleich die Anwendung durch Chuck-Norris-Exceptios beenden (den Fehler sieht man nur beim Debuggen, im wirklichen Leben wird "die Anwendung nach einem schwerwiegenden Fehler beendet", der Fehler lässt sich nicht in einer Messagebox anzeigen)

    Stefan

    Montag, 1. November 2010 10:28
  • Hallo Stefan,

    Ja, Zugriffsverletzungen treten zuweilen non-deterministisch auf (oft z.B. wenn das ActiveX-Control oder eine Dependency Multithreading benutzt). Sie werden unter gewissen Voraussetzungen vom Betriebsystem erzeugt und lassen sich oft schwer über Testszenarien nachvollziehen. Es ist beinahe unmöglich zu sagen, was das ActiveX-Control wirklich macht, wenn man nicht den dazugehörigen Sourcecode hat (geht eigentlich nur über hard core debugging) und der Fehler nur dann und wann auftritt (z.B. bei sporadischen Racebedingungen). Der Dritthersteller-Code könnte Exceptions-Hooks installieren und vergessen diese zu deinstallieren, er könnte Memoryleaks verursachen, oder versuchen Nullzeiger zu dereferenzieren usw.

    Du könntest aber entweder einen UnhandledException-Handler einsetzen (u.U. nur bis .NET 4.0 und im Normalfall nur für Hauptthreadexceptions) oder die Drittherstellerkomponente in einem eigenen AppDomain isolieren, so dass diese beim Absturz nicht die ganze Anwendung mitreißt (passiert trotzdem, wenn die Drittherstellerkomponente oder eine der Abhängigkeiten den aktuellen Prozess insgesamt abbricht). Du könntest ebenfalls eine der verfügbaren Plugin-Technologien einsetzen, die gute Isolation unterstützt, z.B. MAF. Alles kein Pappenstiel.

    s.a. http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/b2cc18d6-e42f-4b36-8174-d65eaddecbb1

    Gruß
    Marcel

    • Als Antwort markiert Stefan Simon Dienstag, 2. November 2010 07:19
    Montag, 1. November 2010 12:58
    Moderator