protected async void DoHeartBeat(string id) { if (HeartBeat <= TimeSpan.Zero) { return; } var timer = new TaskCompletionSource <bool>(); Timers.AddOrUpdate(id, timer, (_, oldtimer) => { oldtimer.TrySetResult(false); return(timer); }); using (CancellationTokenSource source = new CancellationTokenSource()) { #if NET40 var delay = TaskEx.Delay(HeartBeat, source.Token); var task = await TaskEx.WhenAny(timer.Task, delay).ConfigureAwait(false); #else var delay = Task.Delay(HeartBeat, source.Token); var task = await Task.WhenAny(timer.Task, delay).ConfigureAwait(false); #endif source.Cancel(); if (task == delay) { timer.TrySetResult(true); } } if (await timer.Task.ConfigureAwait(false) && Messages.TryGetValue(id, out var topics)) { foreach (var topic in topics.Keys) { Offline(topics, id, topic, new ServiceContext(Service)); } } }