2013-07-05 109 views
0

今天我遇到一些奇怪的行爲。我有一個串行設備,我使用SerialPort類訪問。主應用程序有一些定時器每秒輪詢一次設備的狀態更新。在某個時候,我需要做一些耗時的工作,因此不要阻止我使用Backgroundworker的GUI。後臺工作者需要一次訪問相同的串行設備。有時訪問有時不起作用。經典mutli-thread方案。所以我嘗試在發送新命令到串口設備的函數上使用Mutex。C#多線程和串口通訊

對於串口設備,我把所有東西放在它自己的類中。在這個類中,我有一個sendCommand()函數,它將命令寫入設備,並使用AutoResetEventOnDataReceived事件來等待答案。 sendCommand函數阻塞,直到接收到答案或發生超時。然後,我在所有可能的出口處輸入sendCommand和releaseMutex時添加了Mutex。仍然不起作用。

有沒有更好的方法來處理這個問題?

感謝, 托比亞斯

+0

releaseMutex?使用C#?只需將整個函數包裝在一個lock()語句中? –

+0

您是否看到錯誤消息或應用程序是否鎖定,等待互斥鎖釋放? –

+0

您的設備不支持雙工通道? – Suhan

回答

1

我做這個事是完全相同的應用程序 - 我所做的是我創建了一個串行訪問類,每當我把它叫做(從GUI或我的一個後臺線程)我會有以下內容:

private void myFunction(SerialClass myserialobject) { 
    if (myserialobject == null) 
    return; 
    lock (myserialobject) { 
    // code accessing the serial object 
    // ... 
    // when finished, close the lock statement 
    } 
} 

我在主線程和任何其他需要訪問的線程中都使用了它。它阻塞了,但我相信這是一個阻塞聲明。

此外,我沒有使用事件處理函數OnDataReceived事件,我讓我的串行對象在任何寫入後執行阻止讀取,這樣可以防止在錯誤的上下文中接收任何數據。我不確定您的程序是如何設置的,但您可能需要考慮這樣做。如果知道在寫入端口時您希望讀取的字節數,它的效果最好;這樣你就不必使用Sleep來確保所有數據都被讀取。

+0

謝謝你的建議。我不知道要接收的字節數。這是一個ASCII類型的協議,其中命令由換行符分隔。收到空行後,我必須解析並檢查之前收到的內容。它可以是從零到四的任何數據。所以我使用'OnDataReeived'並將所有內容寫入緩衝區,直到我收到一個空行。然後我設置一個'AutoResetEvent'來發信號通知我的'SendCommand'例程來處理數據。 'SemdCommand'阻塞,直到收到數據或發生超時。 – thefloe

0

我通常所做的是在循環中運行串行讀/寫線程,以定時等待的方式從BlockingQueue讀取命令。如果在超時時間內收到一個串行請求對象,則線程執行它,如果等待超時,線程將執行對串行設備的輪詢。