Buddhike hit a hiccup the other day with a multi-threaded client that bears explanation.
The Channel layer always requires an explicit Open() before it can be used. This enforces our CommunicationObject state machine. As a usability feature, our ServiceChannel proxy code supports “auto-open”. That is, you can call a proxy method without explicitly calling Open and the runtime will call Open() on your behalf. This is transparent in the case where you are using a proxy synchronously from a single thread. However, if you are using a proxy asynchronously (or from multiple threads), you may have the case that the Open() is associated with the first request, but subsequent requests are also pending.
Since the state machine is that Open() must complete before Send/Receive are valid operations, none of the requests can proceed until Open completes. In the shipping code, this synchronization is actually around the entire ServiceChannel call, and so Buddhike was seeing an excessive delay. We’ll investigate for the next version if there’s a way in unblock earlier on the client, while still providing all of our existing behavioral guarantees. In the interim, I recommend two things when using a client asynchronously and/or from multiple threads concurrently:
- Open your client explicitly prior to usage. You can do this sychronously or asynchronously depending on your application
- Prefer calling your client asynchronously to spinning up multiple threads for synchronous calls if you want better scalability/thread-usage