Autor Beitrag
stdue
Hält's aus hier
Beiträge: 5



BeitragVerfasst: Mi 07.12.11 13:17 
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
ausblenden C#-Quelltext
1:
SerialPort serialPort = new SerialPort()					

erstellte und mit
ausblenden 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
ausblenden C#-Quelltext
1:
serialPort.DataReceived -= new SerialDataReceivedEventHandler(OnPort_DataReceived);					

und etwa wie in www.codeproject.com/...m/DriveDetector.aspx beschrieben
überwacht wird. Dazu wir WndProc überschrieben.
In dieser Funktion landet beim debuggen das Programm mehrfach
ausblenden 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)
        {
            // call the base class WndProc for default message handling
            base.WndProc(ref m);    
            try
            {
                if (mDetector != null)
                {
                    mDetector.WndProc(ref m);   //call WndProc(ref System.Windows.Forms.Message m)
                }

            }
            catch (InvalidCastException ex)
            //catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);

                //throw new System.NotImplementedException();
            }
        }

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:
ausblenden 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
ausblenden 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 user profile iconTh69: C#-Tags hinzugefügt
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4796
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: 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
ausblenden 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
ausblenden 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.

Für diesen Beitrag haben gedankt: stdue
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: 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 Threadstarter
Hält's aus hier
Beiträge: 5



BeitragVerfasst: 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.
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
      private void OnDriveChanged(object sender, PortDetectorEventArgs e)
        {
/* not relevant
            // Report the event in the listbox.
            rtfData.AppendText(DateTime.Now.ToLongTimeString() + " USB COM PORT " + e.Drive + "\n");
            ArrayList arrayList = PortDetector.returnArrayList;   //read global List
            viewPortListArray(arrayList);
*/

            if (e.Drive == "Removed"//&& serialPort.IsOpen)
            {
                serialPort.Close();
                [b]serialPort.Dispose();[/b]
            }
        }
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: 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.

Für diesen Beitrag haben gedankt: stdue
ujr
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 102
Erhaltene Danke: 12



BeitragVerfasst: Mi 07.12.11 16:38 
Hallo,

möglicherweise hilft irgendeiner der auf den folgenden Seiten genannten Tipps:
connect.microsoft.co...e-while-port-is-open
connect.microsoft.co...nect-of-usb-com-port
connect.microsoft.co...rizedaccessexception

Für diesen Beitrag haben gedankt: stdue
stdue Threadstarter
Hält's aus hier
Beiträge: 5



BeitragVerfasst: Mi 07.12.11 17:19 
Anmerkung zum Dispose(): In PrgName.designer.cs seht doch am Anfang:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
    /// <summary>
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.IContainer components = null;

    /// <summary>
    /// Clean up any resources being used.
    /// </summary>
    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    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?
stdue Threadstarter
Hält's aus hier
Beiträge: 5



BeitragVerfasst: Mi 07.12.11 17:33 
Danke @ujr für die Links. Unter
connect.microsoft.co...nect-of-usb-com-port
ist da öfter zu lesen "I have the same problem. With a FTDI USB serial port device.."
Problemursache geht jetzt also in Richtung FTDI USB-Treiber, die verwende ich auch!
Steffen
ujr
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 102
Erhaltene Danke: 12



BeitragVerfasst: Mi 07.12.11 17:41 
user profile iconstdue hat folgendes geschrieben Zum zitierten Posting springen:
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.

Für diesen Beitrag haben gedankt: stdue
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: 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.

Für diesen Beitrag haben gedankt: stdue
stdue Threadstarter
Hält's aus hier
Beiträge: 5



BeitragVerfasst: 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