【发布时间】:2018-10-17 15:13:23
【问题描述】:
我有一个低级 CAN 设备类,我想为其创建一个 onMessageReceive 事件。我有几个可以使用这个 CAN 类的实例的高级设备类。我想将高级设备类的消息解析器附加到低级 CAN 设备 onMessageReceive 事件。这样,当低级类接收到一个数据包时,低级读取器任务会将其解析为高级类。放入代码中,如下所示。
void Main()
{
try
{
using (HighLevelDevice highLevelDevice = new HighLevelDevice())
{
while (true)
{
// Use the properties/fields in highLevelDevice to make testing decisions.
}
}
}
catch (Exception)
{
// If the low level CAN reader task encounters an error I would like for it to asynchronously propogate up to here.
throw;
}
}
public class HighLevelDevice
{
private LowLevelCan lowLevelCanInstance;
public HighLevelDevice()
{
lowLevelCanInstance = new LowLevelCan(this.ProcessPacket);
}
private void ProcessPacket(Packet packet)
{
// Convert packet contents into high level device properties/fields.
}
}
public class LowLevelCan
{
private delegate void ProcessPacketDelegate(Packet packet);
private ProcessPacketDelegate processPacket;
private Task readerTask;
public LowLevelCan(Action<Packet> processPacketFunction)
{
processPacket = new ProcessPacketDelegate(processPacketFunction);
readerTask = Task.Run(() => readerMethod());
}
private async Task readerMethod()
{
while(notCancelled) // This would be a cancellation token, but I left that out for simplicity.
{
processPacket(await Task.Run(() => getNextPacket()));
}
}
private Packet getNextPacket()
{
// Wait for next packet and then return it.
return new Packet();
}
}
public class Packet
{
// Data packet fields would go here.
}
如果在 getNextPacket 中抛出异常,我希望它在 main.xml 中被捕获。这有可能吗?如果我偏离了基础并且完全误解了异步,我深表歉意。如果这样的事情是可能的,我怎么能改变我的方法来实现它?我可以定期检查阅读器的状态,但如果可能的话,我想避免这种情况。
这个实现会杀死阅读器,但 highLevelDevice 线程不经意地继续。如果我存储错误并偶尔在主线程上检查状态,那就没问题了。如果可能的话,我只想找到一个避免这种情况的解决方案。
我尝试了在 highLevelDevice 退出的线程上创建的错误报告事件和进度报告的变体。这些不能按预期工作/或我不明白他们在做什么。
【问题讨论】:
-
你试过这个,发现它不起作用?这通常是检查某事是否可能的最简单方法......
-
我已经尝试了几种变体。当抛出异常时,读取器线程将死亡,但创建高级设备的线程继续在不经意间运行。
-
如果有问题,那将是很好的信息。随意edit您的问题,包括您尝试过的内容。请参阅How to Ask,了解有关我们在问题中寻找什么的更多提示。我们可以看到问题的编辑历史,因此无需告诉我们您编辑了什么。
-
您的意图是低级设备将运行一个循环,通过事件将更改推送到高级设备(此时您的代码仅读取单个数据包)?而您的
Main循环访问高级设备而不关心其状态在后台发生变化? -
@pere57 这就是我想做的。我将其编写为示例代码,以显示我想在实际代码中实现的目标。我修复了丢失的 while 循环。谢谢。真正的数据包具有时间戳信息,如果我想知道上次更改的时间,我可以检查这些信息。通常虽然我不关心通知所有更新的主循环。我确实关心主循环收到接收循环中的错误通知。错误,例如:无数据、错误数据或硬件断开连接。据我所知,我必须检查任务状态才能看到错误。我只是希望有人能告诉我另一种方式。
标签: c# asynchronous exception-handling async-await producer-consumer