Hallo Allerseits,
ich habe ein Problem mit einem meiner Programme beim ausführen unter Win7 (32 und 64 Bit).
Unter Win XP tut es was es soll.
Das Problem hängt mit einem von mir verwendeten SerialPort zusammen. Hardware technisch verwende ich einen USB Converter.
Aus verschiedenen Stellen des Programms greife ich nach ein ander auf dieses Gerät zu. Deshalb öffne ich die Verbindung, mache meine Übertragungen und schließe es wieder.
Nun die Fehlerbeschreibung: Wenn ich das erste mal eine Verbindung herstelle, d.h. USB eingesteckt, Serialport geöffnet, senden, empfangen, schließen, Funktion Ende, funktioniert das ganze tadellos. Aber bereits beim nächsten Verwenden wird nichts mehr empfangen. Senden funktioniert weiterhin. Mit einem anderen Rechner lese ich die Daten auf dem Bus mit, es findet eigentlich eine saubere Kommunikation statt. Aber wie gesagt, es wird nichts empfangen.
Getestet habe ich zusätzlich mit einem anderen .Net bassierten Programm, welches zum Mitschreiben der Busaktivität dient. Hier ist das Verhalten identisch. Wird die Verbindung geschlossen, und wieder geöffnet, wird nicht Empfangen.
Durch entfernen des USB-Steckers und wieder hineinstecken kann das Problem gelöst werden, bis das nächste mal der Serialport geschlossen wird.
Was ich bisher versucht habe, ist dass ich mich nicht wie vorher darauf verlassen habe, dass die Instanz der Serialportklasse am ende der Funktion zerstört wird, sondern ich habe sie "von Hand'" Disposed. Dies hat leider nichts gebracht.
Gibt es hier bekannte Schwierigkeiten? Muss ich noch mehr "von Hand" aufräumen? Oder vermutet ihr ein Treiber Problem?
Die Treiber Problematik möchte ich eigentlich ausschließen, da ein C++ Programm ohne Probleme mit diesem Gerät arbeitet.
Gruß Daniel
edit: Es werden keine Exceptions geworfen. Da ich auf eine Antwort warte, erkennt das Programm selbst, dass nicht geantwortet wurde. Ich habe außerdem ein kleines tool geschrieben, um das Event verhalten zu Testen, dieses Verhält sich gleich.
Ich möchte euch noch ein wenig Code zur Verfügung stellen. Ich habe die Funktion ein wenig gekürzt, aber hoffentlich alles relevate Dringelassen.
private bool SendeEinenEingang( )
{
DateTime aktuell = new DateTime();
TimeSpan timeOut = new TimeSpan(3500000);//=>350ms
//Erstellen einer neuen SerialPort Instanz
SerialPort port = ErstellePort( portname );
if ( port != null )
{
//Lese Eingang aus
int eingang = /*hier wird die Anzahl ermittelt*/;
//Erzeugen der fortlaufenden Nummer für den Eingang, real 1-10, 19-28
if ( eingang > 10 )
{
eingang = eingang - 8;
}
//Erzeugen eines schreibe Puffers, fülle mit Daten
byte[] ausgangsPuffer = new byte[ 6 ];
ausgangsPuffer[ 0 ] = busAdresse;
ausgangsPuffer[ 1 ] = Convert.ToByte( eingang - 1 );
ausgangsPuffer[ 2 ] =/*weitere Daten*/;
/* Noch mehr Daten*/
for(...)
{
try
{
//Öffnen des SerialPorts
port.Open();
string[] ports = System.IO.Ports.SerialPort.GetPortNames();
bool vorhanden = false;
for (int i = 0; i < ports.Length; i++)
{
if (ports[i] == portname)
vorhanden = true;
}
if (!vorhanden)
{
return false;
}
if (port.IsOpen)
{
//Senden des Protokolls
port.Write(ausgangsPuffer, 0, ausgangsPuffer.Length);
int zaehler = 0;
//Hohle aktuelle Systemzeit für Timeout
aktuell = DateTime.Now;
//Warte auf genug Daten oder Timeout
while (!(port.BytesToRead >= bytesToRead)
&& ((aktuell + timeOut) > DateTime.Now))
{ zaehler++; }
//Es liegen genug Daten im SerialPort Puffer
if ((port.BytesToRead == bytesToRead)
|| (port.BytesToRead > 12))
{
//Erstellen eines Eingangspuffers
byte[] eingangsPuffer = new byte[bytesToRead];
//Einlesen der empfangenen Daten
port.Read(eingangsPuffer, 0, eingangsPuffer.Length);
//Schließen des SerialPorts
port.Close();
//Festlegen ob ein Offset nötig ist, wenn ja wie groß
int offset = 0;
if (eingangsPuffer[0] != 0xBD)
offset = 6;
//Prüfen ob die Antwort gültig ist, sost Enden
if (!IstKorrekteAntwort(eingangsPuffer,
ausgangsPuffer, offset))
{
//Schließe SerialPort
port.Close();
//Schließe Progress Formular, aktiviere MainForm
fortschrittsUebertragungsForm.Schließen(false, ref hauptForm);
//Öffne Fehlermeldung
ErrorMessage fehlerForm = new ErrorMessage();
fehlerForm.ZeigeFehlerDialog("Fehler",
"Bei der Übertragung kam es zu Komplikationen",
"es wurde nicht geantwortet", true);
return false;
}
}
else
{
//Schließe SerialPort
port.Close();
//Schließe Progress Formular, aktiviere MainForm
fortschrittsUebertragungsForm.Schließen(false, ref hauptForm);
//Öffne Fehlermeldung
ErrorMessage fehlerForm = new ErrorMessage();
fehlerForm.ZeigeFehlerDialog("Fehler",
"Bei der Übertragung kam es zu Komplikationen",
"es wurde nicht geantwortet", true);
return false;
}
//Zeige den Fortschritt an
fortschrittsUebertragungsForm.NaechsterSchritt
(/*Fortschritts Handling*/);
}
else //if ( port.IsOpen )
{
istErfolgreich = false;
}
}
catch (Exception e)
{
if (e is System.UnauthorizedAccessException || e is System.InvalidOperationException || e is System.IO.IOException)
{
if (e is System.InvalidOperationException)
{
//Schließe SerialPort
port.Close();
}
//Schließe Progress Formular, aktiviere MainForm
fortschrittsUebertragungsForm.Schließen(false, ref hauptForm);
//Öffne Fehlermeldung
ErrorMessage fehlerForm = new ErrorMessage();
fehlerForm.ZeigeFehlerDialog("Fehler",
"Bei der Übertragung kam es zu Komplikationen",
"Die USB Verbindung wurde unterbrochen. bitte überprüfen sie "
+ "den Anschluss der Schnittstelle", true);
return false;
}
}
} //for ( ...)
port.Dispose();
return true;
} //if ( port != null )
else
{
return false;
}
}
Hallo,
Gibt es hier bekannte Schwierigkeiten? Muss ich noch mehr "von
Hand" aufräumen? Oder vermutet ihr ein Treiber Problem?
Ich vermute eher ein Problem mit dem Treiber, denn bei mir funktioniert das mehrmalige schließen und wieder öffnen des Ports ohne Probleme unter Win7 (64Bit) und ich habe ebenfalls einen USB/Serial Converter (von FTDI).
Hast du denn einen OnBoard-Port verfügbar mit dem du testen kannst, oder einen anderen Wandler?
Gruß
Ich habe ein anderes Programm, welches auf diese Hardware zugreift. Dieses ist in C++ geschrieben und läuft ohne Probleme, ich weiß jedoch nicht, ob dieser den SerialPort mehrfach oder nur einmal Öffnet.
Dem Treiber werde ich mich nochmal annehmen. bzw. mal eine andere Hardware Testen.
Hallo,
benutze einen Sniffer wie "Portmon" (Portmon für Windows 3.02) und vergleiche Öffnen, Datentransfer und Schließen des Ports.
Danke für die Hilfe.
Unser Lieferant hat die Treibersoftware umgestellt. Mit einem älteren Treiber bin ich unter der 32 Bit Version klar gekommen. Für 64 Bit habe ich aktuell keine Treiber, da muss ich mich drum kümmern.
Portmon ist leider unter Win7 wohl nicht lauffähig und wird anscheinend von Microsoft seit 2006 nicht mehr weiterentwickelt.
Gruß Daniel