2009-11-08 17 views
6

Mam automatycznie wykrywany wątek, który próbuje otworzyć porty w kolejności i dopasować odebrane dane, tym samym wykrywając port, w którym odpowiednie urządzenie wysyła dane. Teraz istnieje kilka portów, w których SerialPort.Open po prostu zawiesza wątek na ~ 30 sekund. Jak ustawić limit czasu dla funkcji SerialPort.Open?C#: Limit czasu na SerialPort.Open?

+1

Czy przeglądasz porty szeregowe z GetPortNames (http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.getportnames.aspx) lub czy próbujesz otworzyć COM1, COM2 itp.? – SwDevMan81

+0

Mam ten sam problem. Rozwiązałeś to w międzyczasie? Pozdrawiam – tamberg

+0

Mam ten sam problem. Byłoby miło, gdyby istniała własność 'OpenTimeout'. –

Odpowiedz

1

Dodaj to w kodzie:

commPort = new SerialPort(); 

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

A ja proponuję, aby zobaczyć SerialPort.Open Method

+0

już zrobione ... – gdario

+0

OK, mam nadzieję, że to pomoże jeszcze jeden;) –

+0

dlaczego nie 'SerialPort.InfiniteTimeout' następnie –

1

Jeśli ja zrozumiałem, chcesz odczytać dane z portu szeregowego, nawet po wystąpieniu limitu czasu.

Jeśli tak, to powinieneś złapać wyjątek TimeoutException i kontynuować tworzenie pętli. na przykład MSDN CODE

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

Nie wydajesz się rozumieć. "SerialPort.Open po prostu zawiesza wątek na ~ 30 sekund". To jest porblem. – gdario

+0

Przepraszam, czy mam teraz usunąć tę odpowiedź? –

+0

Nie, przyda się komuś innemu. – gdario

3

Od MSDN
Tylko jedno otwarte połączenie może istnieć za obiekt SerialPort.

Najlepszą praktyką dla każdej aplikacji jest oczekiwanie na pewien czas po wywołaniu metody Close przed próbą wywołania metody Open, ponieważ port może nie zostać natychmiast zamknięty.

Po wywołaniu Close() ten wątek roboczy potrzebuje czasu na obrót i wyjście. Wymagany czas nie jest określony i nie można zweryfikować, czy zostało ono wykonane. Wszystko, co możesz zrobić, to odczekać przynajmniej sekundę, zanim ponownie zadzwonisz do Open().

+0

+1 do części dotyczącej czasu na otwarcie SerialPort po jej zamknięciu. Pomogło mi to poprawić kod. – Yetti

2

Wystąpił ten sam problem i mam nadzieję, że moje rozwiązanie może ci pomóc.

Możesz wykryć porty szeregowe w osobnym wątku, który zostanie przerwany w ciągu 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 !"; 
     } 
     } 
    } 
} 

Możliwe rozwiązania mogą zostać dodane do rozwiązania. Możesz użyć wielu wątków, aby przyspieszyć proces i użyć ProgressBar, aby wyraźnie wyświetlić postępy.