In general, all our SDK are thread safe.
If the card has one, two or four channels does not matter. One channel does not know if it has a “neighbour” or not. In the SDK you can open a HANDLE to a channel. It is important that all instances opens its own HANDLE to the channel, even if it is the same channel.
Open Multiple Thread Safe Channels
You can open handles to a channel anytime after the canInitializeLibrary call. Does not matter if you have placed a handle bus on or not.
The problem with your code is in way you evaluate the returned value of the canOpenChannel call:
int hnd = Canlib.canOpenChannel((int)Identity,Canlib.canOPEN_ACCEPT_VIRTUAL);
canOpenChannel returns a canStatus if the function call fails. All canStatus error codes have a negative value. If the status returned is 0 or greater, then the value is a valid handle.
If the value returned is 1 on the second call to canChannelOpen, this means a handle value of 1 was returned, not an error status.