I have a low level CAN device class that I would like to create an onMessageReceive event for. I have several high level device classes that could use an instance of this CAN class. I would like to attach the high level device class' message parser to the low level CAN device onMessageReceive event. Such that when the low level class receives a packet it is parsed into the high level class by the low level reader task. Put into code it would look like the following.
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.
}
If an exception is thrown in getNextPacket I would like that to be caught in main. Is this possible in any way? If I am way off base and completely misunderstanding async I apologize. If something like this is possible how could I change my approach to achieve it? I could check the state of the reader periodically, but I would like to avoid that if possible.
This implementation will kill the reader, but the highLevelDevice thread continues obliviously. This would be okay if I stored the error and checked the status occasionally on the main thread. I would just like to find a solution that avoid that, if possible.
I have tried variations of error reporting events and progress reporting created on the thread that the highLevelDevice exits on. These do not work as expected/or I do not understand what they are doing properly.