InitializeAsync catch block now mirrors ShutdownAsync teardown: cancels and disposes probe CancellationTokenSources, calls DisposeRuntimes, and clears _devices/_tagsByName before rethrowing. A caller that catches and abandons (rather than retrying via ReinitializeAsync) no longer leaves orphaned probe tasks or libplctag handles alive. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>