[英]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.