@TomWr你是對的,從我正在閱讀的是這種情況。
你下面有我的評語摘錄:
try
{
// Let's check how many bytes are available on the Serial Port
btr = serialPort1.BytesToRead;
// Something? Alright then, let's wait 300 ms.
if (btr > 0)
Thread.Sleep(300);
// Let's check again that there are some bytes available the Serial Port
btr = serialPort1.BytesToRead;
// ... and if so wait (maybe again) for 300 ms
// Please note that, at that point can be all cumulated about 600ms
// (if we actually already waited previously)
if (btr > 0)
{
Thread.Sleep(300);
btr = serialPort1.BytesToRead;
numbytes = serialPort1.Read(stuffchar, 0, btr);
for (x = 0; x < (numbytes); x++)
{
// Seems like a useless overhead could directly use
// an Encoding and ReadExisting method() of the SerialPort.
cc = (stuffchar[x]);
stuff += Convert.ToString(Convert.ToChar((stuffchar[x])));
}
我的猜測是同它上面通過idstam已經述及,基本上可能要檢查是否是數據由設備發送和獲取它們
你可以用適當的SerialPort方法輕鬆重構這段代碼,實際上有更好更簡潔的方法來檢查串口上是否有數據可用。
而不是「我正在檢查端口上有多少字節,如果有什麼,然後我等待300毫秒,然後再次相同的事情。「這很可悲地結束於
」所以是2倍300毫秒= 600毫秒,或只是一次(取決於是否有第一次「,或者什麼也沒有(取決於你通過這個用戶界面進行通信的設備)因爲Thread.Sleep會阻止用戶界面......)。「
首先讓我們考慮一段時間,您試圖保持儘可能多的相同的代碼庫,爲什麼不等待600ms?
或者爲什麼不只是使用ReadTimeout屬性和捕捉超時異常,不是那麼幹淨,但至少在可讀性方面更好,而且您直接獲取字符串而不是使用一些Convert.ToChar()調用...
我感覺代碼已經從C或C++(或者至少是背後的原理)移植到了主要是嵌入式軟件背景的人身上。
無論如何,回到可用字節檢查的數量,我的意思是除非串行端口數據在另一個線程/ BackgroundWorker/Task處理程序中刷新,否則我沒有看到任何檢查它的兩個原因,特別是以它的方式編碼。
爲了讓它更快?不是真的,如果串行端口上實際存在數據,則會有額外延遲。這對我來說沒有多大意義。
使您的代碼片段稍微好一點的另一種方法是使用ReadExisting()進行輪詢。
否則,您也可以考慮使用SerialPort BaseStream的異步方法。
總而言之,如果不訪問代碼庫的其餘部分,即上下文,很難說。
如果您有更多關於目標/協議的信息,它可以提供一些關於如何做的提示。否則,我可以說這似乎是編碼不好,再一次,脫節。
我甚至把漢斯提到的關於用戶界面響應的問題翻了一番,因爲我真的希望你的代碼片段在一個不是用戶界面的線程中運行(儘管你在帖子中提到用戶界面正在輪詢我仍然希望該片段是爲另一名工人)。
如果這確實是UI線程,那麼每次有Thread.Sleep調用都會阻止它,這會導致UI不能真正響應用戶交互,並且可能會給最終用戶帶來一些挫折感。
可能還需要訂閱DataReceived事件並執行處理程序所需的操作(例如,使用緩衝區和比較值等)。
請注意mono還沒有實現這個事件的觸發器,但是如果你正在運行一個簡單的MS .NET實現,這是完美的沒有多線程的麻煩。
簡而言之:
- 檢查哪個線程(S)爲被照顧您的片斷和心靈有關的UI響應
- 如果是UI,然後通過使用另一個線程線程,BackgroundWorker(線程池)或任務。
- 流異步方法,以避免UI線程同步的
- 嘗試的麻煩,看目標是否真的值得雙300毫秒線程睡眠方法調用
- ,您可以直接獲取字符串代替如果後者檢查正在使用以執行操作而不是自己收集字節(如果所選編碼可以滿足您的需要),則可以採集數據。
流異步方法(例如'port.BaseStream.ReadAsync')不使用另一個線程....這是件好事。您不必擔心從多個線程同步對數據結構的訪問,或者在線程之間編組UI。每當事件處理程序返回或調用「await」時,只需將數據結構保持一致即可。 –
@BenVoigt http://referencesource.microsoft.com/#mscorlib/system/io/stream.cs,e224b4bec8748849 async/await正在使用Task,所以Threadpool。因此它可以在另一個線程上運行,但不一定。 如果你認爲我錯了,隨意解釋一下。 同意特別是當它與用戶界面相關時。 – Ehouarn
任務對象默認在當前上下文中運行,在UI應用程序中,默認上下文是UI消息分派器。沒有使用額外的線程。現在,您可以選擇將任務強制爲工作線程,但這對於I/O尤其是串行I/O來說很愚蠢。工作線程僅對CPU綁定操作有利。 –