private async Task RefreshStateAsync(string id, CancellationToken cancellationToken) { try { // Only allow one concurrent call to the access control system (VMS will likely request status for all doors on startup) await _resolveStateSemaphore.WaitAsync(cancellationToken); try { // Check if status was already updated var state = GetState(id); if (state == null) { try { var doorStatus = await _client.GetDoorStatusAsync(id); cancellationToken.ThrowIfCancellationRequested(); if (doorStatus != null) { state = TypeConverter.ToACState(doorStatus); UpdateState(state); FireStatesChanged(new[] { state }); } } catch (DemoApplicationClientException ex) { // Should probably retry on failure ACUtil.Log(true, "DemoACPlugin.StateManager", "Error refreshing state for door " + id + ": " + ex.Message); } } } finally { _resolveStateSemaphore.Release(); } } catch (OperationCanceledException) { } }