2016-02-05 132 views
0

我正在開發一個通過SerialPort發送和接收命令的應用程序。有時,我與之通信的硬件不響應,如何阻止我的應用程序等待響應?因爲它不允許我重試發送和接收命令。我得到一個「訪問端口'COM#'被拒絕。」當我第二次調用sendRecvCMDAsync()函數時發生異常。如何殺死(不取消)已被調用的異步任務?

這裏是我的SerialPort communicaion代碼,

 public async Task<List<String>> sendRecvCMDAsync(String COMPort, String FW_CMD, List<String> SendParamList, CancellationToken ct) 
    { 
     SL_Port = new SerialPort(); 
     try 
     { 
      if (COMPort != "") 
      { 
       SL_Port.PortName = COMPort; 
      } 
      else 
      { 
       //show a message box; 
      } 

      if (SL_Port.IsOpen) 
      { 
       SL_Port.Dispose(); 
       SL_Port.Close(); 
      } 
      SL_Port.Close(); 
      SL_Port.Open(); 
      SL_Port.WriteLine(FW_CMD); 
      _continue = true; 
      Array.Clear(buffer, 0, buffer.Length); 
      int count = 0; 
      while (_continue) 
      { 
       mess = ""; 
       Task<int> bytes = SL_Port.BaseStream.ReadAsync(buffer, count, buffer.Length - count, ct); 
       int bytesCount = await bytes;//I need to kill this after its started, because it is not alowing me to access the COM port unless it completes. 
       count = bytesCount + count; 
       mess = Encoding.ASCII.GetString(buffer).TrimEnd('\0'); 
       if (mess.Contains("")) 
       { 
        break; 
       } 
       else 
       { 
       } 
      } 
     } 
     catch (OperationCanceledException) 
     { 
      MessageBox.Show("You have Successfuly Cancelled the event"); 
     } 
     catch (Exception e) 
     { 

     } 

     SL_Port.Dispose(); 
     SL_Port.Close(); 
     return listForFW; 
    } 

我呼籲取消,但由於已經執行的代碼等待響應的這是行不通的。

這裏是我的函數調用代碼

public async void startSending() 
{ 
    cts = new CancellationTokenSource(); 
    ReturnParams = await sendRecvCMDAsync(xport, commandSend, paramsList, cts.Token) 
} 

這裏是我的取消呼叫代碼。

public void btnCancelSend() 
{ 
    cts.Cancel(); 
} 

那麼我該如何解決這個問題呢?取消不起作用。

+0

的SerialPort沒有其方法表彰取消。因此,你不能通過這種方式取消。您可能會調用Close,但請注意,基於MSDN文檔有副作用。 –

+0

不幸的是,關閉端口會引發異常。但我想這可以完成這項工作。 –

回答

4

乾淨的唯一方法殺死(如終止)操作是在單獨的進程中運行它。取消應該是首選。

在你的情況下,有取消的另一種方式(這是很容易):傳統上,Win32的異步操作可以通過關閉他們操作手柄上的取消。這將導致所有現有操作完成(出現錯誤)。

注意,這將取消所有操作;特別是如果您在同時閱讀和書寫,這兩個操作都會在您關閉句柄時出錯。

+0

嗨,我與取消的問題是,它不會影響已執行的代碼行。 例如:如果我已經成功發送命令並且現在正在等待接收命令,它將不會停止等待命令。這意味着我無法訪問該端口,直到該操作完成。 –

+0

@MilindaSeneviratne:如果閱讀操作使用'CancellationToken',則可以取消閱讀。如果你做一個「大規模取消」通過關閉句柄,那麼你就可以取消讀取。 –

+0

@StephenCleary:你能詳細一點,也許用一個例子,在任務方面,怎麼一會去「關閉句柄」? –

0

開始自己Thread

待辦事項消息抽你自己。

當硬件發生故障,您可以.Abort()它。你的場景對於異步/等待來說是非典型的。

+0

有沒有更好的方式與硬件通信可能失敗? –

+0

我不太瞭解。順便說一句,有http://electronics.stackexchange.com/。 –

+0

哇,我不知道有一個電子論壇。謝謝! –