How can I perform concurrent, independent OPC operations in different threads using the OPC Data Client?
The OPC Data Client documentation indicates that the EasyDAClient class and related objects are thread-safe. We've confirmed that it's possible to invoke OPC operations from multiple threads using a single EasyDAClient object. However, if any of those operation encounters a failure (e.g. timeout due to broken Ethernet link), then the concurrent operations in other threads will also fail. Is it possible to adjust the EasyDAClient configuration parameters so that cross-thread operations are independent? Is there some other technique which can be employed to achieve this goal?
There are multiple concepts in play, but in general, you are right that there is a central resource that is shared by the calls you are making - even when you are making them from different threads.
Unless chosen otherwise (see further below), the component creates a single connection to each target OPC server (one OPCServer object), and it also minimizes or at least reduces the number of OPC Groups created there.
This is one reason why the results in those threads seem dependent: With a bit of simplification, we can say that there is a single thread that takes care of requests made to each target OPC server. If a function call made to that OPC Server blocks for long time, not only this particular request, but also others that are waiting in queue may time out.
This behavior is by design.
You should be able to get around it by setting the Isolated property to True (this is a property of EasyDAClientMode object, contained in ClientMode property of the main EasyDAClientMode object).
This is how it works: By default, Isolated is False everywhere. All calls made on EasyDAClient objects whose ClientMode.Isolated property is False will use a single, shared connection to each target OPC Server.
If you set ClientMode.Isolated to True, calls made while this is in effect will use a connection to target OPC Server that is specific to that instance of EasyDAClient object you are making call on. So, for example, if you set ClientMode.Isolated to True on each EasyDAClientMode object immediately after you create it, each of these objects will then create and maintain its OWN connection to every target OPC Server. The code can also make dynamic changes to ClientMode.Isolated to achieve various results.
You can reprogram your application so that they use separate instances of EasyDAClient object (one instance per each thing that should remain independent - such as the device in the TOP Server), and set their ClientMode.Isolated to True after creation.
When using TOP Server you will want to make sure each device is in its own separate channel. This way each device can run on a separate thread at the TOP Server level.