[英]c# thread sleep on DataReceived event
我在C#上編寫了這段代碼
public class SerialClass
{
SerialPort s;
public Serial()
{
InitSerialPort();
s.DataReceived += dataReciver;
}
private void dataReciver(object sender, SerialDataReceivedEventArgs e)
{
lock (obj)
{
while (s.BytesToRead >0)
{
var line = s.ReadLine();
if(line=="hello")
{
Thread.Sleep(500);
s.WriteLine("hello to you friend");
}
else //......
}
}
}
}
當我從序列中收到“你好”時,我想在500毫秒后回答“你好,你的朋友”。
我聽到了很多,請不要在代碼上使用睡眠。
這里使用睡眠有什么不利條件? 如果更多數據將通過串行端口傳輸,則新事件將進入dataReciver,因為它將在secondery線程上打開。
那么,什么是缺點?沒有睡眠的更好/最好的方法是什么?
我使用鎖,因為我希望該讀數只有1個線程
如果操作正確,則不需要鎖。
恕我直言,您應該完全避免DataReceived
事件。 將SerialPort.BaseStream
包裝在StreamReader
,然后循環使用異步方法進行讀取。 無論如何,我也不會將延遲(無論是異步還是其他方式)與您的閱讀順序相結合。 您應該隨時准備閱讀。
您沒有提供真實的代碼,因此不可能提供真實的代碼解決方案,但是這是我寫出您發布的部分代碼的方式:
public class Serial
{
SerialPort s;
public Serial()
{
InitSerialPort();
// Ignore returned task...constructors shouldn't wait. You could store
// the task in a class field, to provide a mechanism to observe the
// receiving state.
Task task = ReceiveLoopAsync();
}
private async Task ReceiveLoopAsync()
{
using (StreamWriter writer = new StreamWriter(s.BaseStream))
using (StreamReader reader = new StreamReader(s.BaseStream))
{
string line;
while ((line = reader.ReadLineAsync()) != null)
{
if (line == "hello")
{
// Ignore returned task...we don't really care when it finishes
Task task = RespondAsync(writer);
}
}
}
}
private async Task RespondAsync(StreamWriter writer)
{
await Task.Delay(500);
writer.WriteLine("hello to you friend");
}
}
我遺漏了一些細節,例如異常處理和對任務的更強大的處理。 但是以上是基本思想。 請注意,所有接收都是在一個循環中完成的,不需要跨線程同步。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.