2017-12-08 12 views
0

Ich versuche, die Lesemethode des SerialPort in eine Aufgabe zu packen, die erwartet werden kann, auf diese Weise kann ich die Vorteile der Verwendung eines CancellationToken und des Timeout vom SerialPort-Objekt erhalten. Mein Problem ist, dass ich die Aufgabe nicht dazu bringen kann, eine Abbruch-Ausnahme auszulösen. Hier ist mein Code ...Async Serial Port mit CancellationToken und ReadTimeout

static CancellationTokenSource Source = new CancellationTokenSource(); 

    static void Main(string[] args) 
    { 
     TestAsyncWrapperToken(); 
     Console.WriteLine("Press any key to cancel"); 
     Console.ReadKey(true); 
     Source.Cancel(); 
     Console.WriteLine("Source.Cancel called"); 
     Console.ReadLine(); 
    } 

    static async void TestAsyncWrapperToken() 
    { 
     try 
     { 
      using (var Port = new SerialPort("COM2", 9600, Parity.None, 8, StopBits.One)) 
      { 
       Port.Open(); 
       var Buffer = new byte[1]; 
       await Task.Factory.StartNew(() => 
       { 
        Console.WriteLine("Starting Read"); 
        Port.ReadTimeout = 5000; 
        Port.Read(Buffer, 0, Buffer.Length);       
       }, Source.Token); 
      } 
     } 
     catch (TaskCanceledException) 
     { 
      Console.WriteLine("Task Cancelled"); 
     } 
     catch (TimeoutException) 
     { 
      Console.WriteLine("Timeout on Port"); 
     } 
     catch (Exception Exc) 
     { 
      Console.WriteLine("Exception encountered {0}", Exc); 
     } 
    } 

Ist es, weil die Port.Read-Methode ein blockierender Anruf ist? Irgendwelche Vorschläge?

Antwort

0

Zwei Methoden sind denkbar.

  1. Mit ReadAsync
    Es ist die Stream-Objekt aus dem BaseStream property des SreiaPort Objekt zu erhalten und die Stream.ReadAsync Method (Byte[], Int32, Int32, CancellationToken) verwenden.

    Obwohl es nicht genau übereinstimmenden Inhalt ist, beziehen Sie sich bitte darauf.
    How to cancel Stream.ReadAsync?
    NetworkStream.ReadAsync with a cancellation token never cancels

  2. Mit DataReceivedEvent und SerialDataReceivedEventHandler
    ändern, so dass es mit DataReceivedEvent als Auslöser arbeitet.
    Bitte beachten Sie die Antwort dieses Artikels.
    Sample serial port comms code using Async API in .net 4.5?

P. S.
Wenn Sie mit .NET 4.0 oder niedriger arbeiten möchten, wird der folgende Artikel hilfreich sein.
Es wird auch verwandte Kenntnisse zu den oben genannten sein.
If you must use .NET System.IO.Ports.SerialPort
Reading line-by-line from a serial port (or other byte-oriented stream)

Verwandte Themen