Entwickler-Ecke
WinForms - "System.UnauthorizedAccessException wurde nicht behandelt"
stdue - Mi 07.12.11 13:17
Titel: "System.UnauthorizedAccessException wurde nicht behandelt"
Hallo zusammen,
bin relativer Anfänger/Einsteiger und ich kämpfe in einer Anwendung schon länger mit der oben genannten Exception:
"System.UnauthorizedAccessException wurde nicht behandelt"
beim beenden eines WinForm Programmes über Application.Exit() und lässt sich auch nicht über try/catch an keiner Stelle abfangen.
Dies geschieht allerdings nur dadurch oder in dem Fall wenn vorher eine ganz normal über
C#-Quelltext
1:
| SerialPort serialPort = new SerialPort() |
erstellte und mit
C#-Quelltext
1: 2: 3: 4: 5: 6:
| serialPort.BaudRate = baudRate; serialPort.DataBits = dataBits; serialPort.StopBits = stopBits; serialPort.Parity = parity; serialPort.PortName = portName; serialPort.Open() |
geöffnete Schnittstelle und Datenverbindung (virtuellen COM-Port über USB) extern getrennt (abziehen USB oder Netz aus) wird. Vorher wird diese mit serialPort.Close() natürlich geschlossen, nach Abfrage über IsOpen.
Das ist alles eigentlich kein Problem.
Dazu kommt aber das die Schnittstelle über
C#-Quelltext
1:
| serialPort.DataReceived -= new SerialDataReceivedEventHandler(OnPort_DataReceived); |
und etwa wie in
http://www.codeproject.com/KB/system/DriveDetector.aspx beschrieben
überwacht wird. Dazu wir WndProc überschrieben.
In dieser Funktion landet beim debuggen das Programm mehrfach
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
| protected override void WndProc(ref Message m) { base.WndProc(ref m); try { if (mDetector != null) { mDetector.WndProc(ref m); }
} catch (InvalidCastException ex) { MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
} } |
aber nie in try{}! und dann ohne Exception auf der letzten geschweiften Klammer in der class main,
danach kommt dann die oben genannte Exception. Komplette Meldung für die Zwischenablage lautet:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| "System.UnauthorizedAccessException wurde nicht behandelt. Message="Der Zugriff auf den Anschluss wurde verweigert." Source="System" StackTrace: bei System.IO.Ports.InternalResources.WinIOError(Int32 errorCode, String str) bei System.IO.Ports.InternalResources.WinIOError() bei System.IO.Ports.SerialStream.Dispose(Boolean disposing) bei System.IO.Ports.SerialStream.Finalize() InnerException: |
Wird das Programm normal ohne externe Unterbrechung geschlossen kommt keine Exception.
Windows hat da trotz serial.Port.Close() offensichtlich irgendwelche Probleme die zu diesem Absturz führen.
Vor dem Close habe ich auch schon
C#-Quelltext
1:
| serialPort.DataReceived -= new SerialDataReceivedEventHandler(OnPort_DataReceived); |
u.a. probiert. Was könnte ich da noch machen, um das zu verhindern?
Kann das Programm so keinem übergeben, obwohl sonst alles richtig tut!
Danke für jede Hilfe!
Steffen
Moderiert von
Th69: C#-Tags hinzugefügt
Th69 - Mi 07.12.11 13:56
Hallo Steffen :welcome:
da der Fehler direkt im Finalizer auftritt, scheint dies wohl ein .NET-Fehler zu sein.
Du könntest probieren, mittels
C#-Quelltext
1:
| GC.SuppressFinalize(serialPort); |
zu verhindern, daß in dem Fall dann der Finalizer überhaupt aufgerufen wird.
Oder den GC vor dem Beenden deines Programm mittels
C#-Quelltext
1: 2: 3: 4: 5: 6: 7:
| try { GC.Collect(); } catch { } |
aufzurufen.
Dies sind aber beides nur Workarounds. Vllt. hat jemand anders noch eine bessere Lösung parat?
P.S: Bitte demnächst die C#-Tags selber setzen, danke.
Ralf Jansen - Mi 07.12.11 14:04
Wenn Dispose aus dem Finalizer aufgerufen wird hast du wohl vergessen selbst zum richtigen Zeipunkt Dispose() am SerialPort aufzurufen . Um dieses eigene Dispose kannst du dann ein Exceptionhandling basteln (Es ist ganz schlechter Stil das Dispose Exceptions werfen kann aber Microsoft hat es in ein paar Klassen geschafft das das trotzdem passiert. Serialport gehört scheinbar dazu)
stdue - Mi 07.12.11 16:10
Leider halfen die GC.* Aufrufe nicht, hoffe die an den richtigen Stellen platziert zu haben.
Auch das eigene Dispose (im Eventhandler s. unten) half leider nichts.
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| private void OnDriveChanged(object sender, PortDetectorEventArgs e) {
if (e.Drive == "Removed") { serialPort.Close(); [b]serialPort.Dispose();[/b] } } |
Ralf Jansen - Mi 07.12.11 16:37
Zitat: |
serialPort.Close();
serialPort.Dispose(); |
Beim SerialPort machen Close und Dispose das gleiche. Beides aufzurufen hilft da tatsächlich nicht. Beide rufen aber auch schon GC.SuppressFinalize auf. Wenn bei dir also beim Beenden der Anwendung der Finalizer aufgerufen wird gibt es bei dir einen Codepfad am Close() bzw. Dispose() vorbei. Du solltest also nochmal deinen Sourcecode dahingegen überprüfen. Dein gezeigter Code zum Beispiel wird ja nur aus einem Event gefeuert der mir jetzt nichts sagt aber vom Namen her kann ich mir nicht vorstellen das der garantiert immer vor Beendigung der Anwendung aufgerufen wird.
stdue - Mi 07.12.11 17:19
Anmerkung zum Dispose(): In PrgName.designer.cs seht doch am Anfang:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| private System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } |
Das wird wohl automatisch erstellt, hier kommt das Programm auch durch und sollte doch serialPort mit schliessen?
ujr - Mi 07.12.11 17:41
stdue hat folgendes geschrieben : |
Problemursache geht jetzt also in Richtung FTDI USB-Treiber |
Gerade nicht - es sollte sich eher um einen Fehler im Framework handeln. Auch sind Workarounds beschrieben, die für einige der Poster hilfreich waren.
Ralf Jansen - Mi 07.12.11 17:43
Zitat: |
Das wird wohl automatisch erstellt, hier kommt das Programm auch durch und sollte doch serialPort mit schliessen? |
Nur wenn sich der SerialPort in der Controls Collection der Form befindet (z.B. weil du den SerialPort per Designer auf die Form geworfen hast). Dein ersten Beitrag impliziert aber das du den SerialPort selbst im Code angelegt hast. Für den bist du dann auch selbst verantwortlich und mußt dafür sorgen das der sauber disposed wird.
stdue - Do 08.12.11 11:17
Aufgrund der Hinweise hier auf ein fehlerhaftes Framework habe ich das Programm jetzt mit VisualStudio Express 2010 und der damit möglichen Umstellung von .NET 3.5 auf 4.0 getestet.
Da mit läuft es jetzt!
Danke
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!