2009-11-08 5 views
6

Je dispose d'un thread d'autodétection qui essaie d'ouvrir les ports dans l'ordre et de faire correspondre les données reçues, détectant ainsi le port sur lequel le périphérique concerné envoie les données. Maintenant, il y a quelques ports où le SerialPort.Open accroche simplement le fil pendant ~ 30 secs. Comment puis-je définir un délai d'expiration sur la fonction SerialPort.Open?C#: Timeout sur SerialPort.Open?

+1

Etes-vous en train d'itérer sur les ports série à partir de GetPortNames (http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.getportnames.aspx) ou essayez-vous juste d'ouvrir COM1, COM2, etc? – SwDevMan81

+0

J'ai le même problème. Avez-vous résolu cela en attendant? A bientôt – tamberg

+0

J'ai le même problème. Ce serait bien s'il y avait une propriété 'OpenTimeout'. –

Répondre

1

Ajouter dans votre code:

commPort = new SerialPort(); 

commPort.ReadTimeout = 1000000; 
commPort.WriteTimeout = 1000000; 

Et je vous suggère de voir SerialPort.Open Method

+0

déjà fait ... – gdario

+0

Ok, j'espère que cela aide un autre;) –

+0

pourquoi pas 'SerialPort.InfiniteTimeout' alors –

1

Si je vous ai bien compris, vous souhaitez lire les données du port série, même après le délai est survenu.

Si tel est le cas, vous devriez alors attraper le TimeoutException et continuer votre boucle. par exemple. MSDN CODE

public static void Read() 
{ 
    while (_continue) 
    { 
     try 
     { 
      string message = _serialPort.ReadLine(); 
      Console.WriteLine(message); 
     } 
     catch (TimeoutException) { } 
    } 
} 
+0

Vous ne semblez pas comprendre. "SerialPort.Open suspend simplement le fil pendant ~ 30 secondes". C'est le porblem. – gdario

+0

désolé, dois-je supprimer cette réponse alors? –

+0

Non, ce sera utile pour quelqu'un d'autre. – gdario

3

De MSDN
Une seule connexion ouverte peut exister par objet SerialPort. La meilleure pratique pour toute application est d'attendre un certain temps après avoir appelé la méthode Close avant d'essayer d'appeler la méthode Open, car le port peut ne pas être fermé instantanément. Lorsque vous appelez Close(), ce thread de travail a besoin de temps pour tourner et quitter. La quantité de temps nécessaire n'est pas spécifiée et vous ne pouvez pas vérifier que cela a été fait. Tout ce que vous pouvez faire est d'attendre au moins une seconde avant d'appeler à nouveau Open().

+0

+1 à la partie sur le fait de prendre le temps d'ouvrir le SerialPort après la fermeture. Cela m'a aidé à améliorer le code. – Yetti

2

J'ai rencontré le même problème et j'espère que ma solution peut vous aider.

Vous pouvez détecter les ports série dans un thread séparé, qui sera annulé en 500 ms.

// the Serial Port detection routine 
private void testSerialPort(object obj) 
{ 
    if (! (obj is string)) 
     return; 
    string spName = obj as string; 
    SerialPort sp = new SerialPort(spName); 

    try 
    { 
     sp.Open(); 
    } 
    catch (Exception) 
    { 
     // users don't want to experience this 
     return; 
    } 

    if (sp.IsOpen) 
    { 
     if (You can recieve the data you neeed) 
     { 
      isSerialPortValid = true; 
     } 
    } 
    sp.Close(); 

} 

// validity of serial port   
private bool isSerialPortValid; 

// the callback function of button checks the serial ports 
private void btCheck(object sender, RoutedEventArgs e) 
{ 
    foreach (string s in SerialPort.GetPortNames()) 
    { 
     isSpValid = false; 
     Thread t = new Thread(new ParameterizedThreadStart(testSerialPort)); 
     t.Start(s); 
     Thread.Sleep(500); // wait and trink a tee for 500 ms 
     t.Abort(); 

     // check wether the port was successfully opened 
     if (isSpValid) 
     { 
      textBlock1.Text = "Serial Port " + s + " is OK !"; 
     } 
     else 
     { 
      textBlock1.Text = "Serial Port " + s + " retards !"; 
     } 
     } 
    } 
} 

Des améliorations possibles pourraient être ajoutées dans la solution. Vous pouvez utiliser multi-thread pour accélérer le processus et utiliser ProgressBar pour afficher la progression clairement.