I was going to say that it’s not a good idea to sleep in the constructor, but I see the GHI Ethernet_J11D driver constructor has a Thread.Sleep(500) in it.
But also notice how that driver doesn’t acquire an important resource (the networking stack) until a separate method call “UseThisNetworkInterface”
The CAN driver has an “InitializeCAN” method.
I think it all comes down to how expensive or rare the resource is.
If, from the constructor, you spin up another thread for the init, you’ll still end up in the invalid state when the constructor finishes.
I just don’t think sleeping for a second or more is a good thing to do in the constructor.
Finally, keep in mind that the constructor with the socket number is used by the designer. You need to ensure that’s not doing resource acquisition.
I looked in the Module Builder’s guide, and this is what it has to say about constructors (emphasis mine):
[quote]Each module must supply a constructor of form shown in the following example. In
this case there are two required sockets, but there could be any number of required
and optional sockets.
// Note: A constructor summary is auto-generated by the doc builder.
/// <param name="socketNumber">The socket that this module is plugged in to.</param>
/// <param name="socketNumberTwo">The second socket that this module is plugged in
public InterestingSensor(int socketNumber, int socketNumberTwo)
For optional sockets, the constructor must accept the value Socket.Unused to mean
"This optional functionality is not used" (Socket.Unused is a static property defined in
the Socket class).
Modules may define additional constructors, but these will NOT be used by the
graphic designer. Modules MUST NOT have functionality in constructors that can’t
also be accessed through methods/properties.
Certain types of modules can usefully derive from some intermediate abstract
classes, such as NetworkModule, DaisyLinkModule, DisplayModule, and
SimpleGraphicsInterface. These are nested classes under Gadgeteer.Module.
Modules that use an intermediate class may need to pass values to that class as part
of each constructor that uses the base keyword. The following example shows a
/// <param name="socket">The mainboard socket that has the <see cref="Relay"/> module plugged into it.</param>
public Relay(int socketNumber)
: base(socketNumber, 0x12, 0, 2, 2, 50, "Relay")
So then I went back and looked at what my MIDI module does (it’s been a while since I touched that code)
And there you go. I’m a hypocrite
public MidiModule(int socketNumber)
Socket socket = Socket.GetSocket(socketNumber, true, this, null);
// need a UART/USART socket.
throw new GT.Socket.InvalidSocketException("Socket '" + socketNumber + "' does not support the MIDI module. Please plug the MIDI module into a socket labeled 'U'.");
// initialize serial comms
_serial = new GTI.Serial(
ActiveSenseMode = MidiActiveSenseMode.AutomaticallyRespond;
FilterToChannel = MidiChannel.ChannelOmni;
AutoFlushSerialOutput = true;
// open ze port
_serial.AutoReadLineEnabled = false;
Going back to the module builder’s guide info, though, I’m tempted to refactor that so you can open/close the serial port using methods, and not have that happen automatically happen in the constructor.
Rambling, and likely didn’t clear anything up, but I hope it gave you some more to consider.