Why does my program hang when I destroy a communicator?
Communicators must be destroyed prior to the termination of the main thread in your program. The destruction of a communicator involves a number of tasks, such as:
- Waiting for requests and callbacks to complete
In a server, any incoming requests that have already been dispatched are allowed to complete and object adapters are deactivated so that no new requests are dispatched. In a client, AMI callbacks are allowed to complete.
- Terminating background threads
The Ice run time uses various "helper" threads that must be stopped.
- Closing connections
After all incoming requests have completed on a connection, Ice gracefully closes the connection.
The destroy
operation does not return until all of these tasks have completed. Aside from cleaning up internal resources, much of this processing involves waiting for application activity to cease. Consequently, some aspects of communicator destruction are not under Ice's control. For example, if a long-running request is already active when the server attempts to destroy its communicator, destroy
will block until that request completes, the reply (if any) is sent, and the connection is gracefully closed. If your application uses long-running requests yet you do not want destroy
blocking until these requests complete, you will need to implement a mechanism for interrupting them.
An application can also cause destroy
to hang by neglecting to complete an Asynchronous Method Dispatch (AMD) request. As far as the Ice run time is concerned, a twoway request is still pending until the server invokes the AMD callback object to report success or failure.
Finally, networking issues or ill-behaved peers can interfere with Ice's attempt to gracefully close a connection. This process involves sending the peer a notification that the connection is being closed and waiting for the peer's acknowledgment. To prevent Ice from waiting indefinitely, we recommend setting timeouts in your proxy endpoints and object adapter endpoints. You can set the property Ice.Trace.Network=2
to discover which connections are not being closed in a timely manner.