public WatchLockModel WatchLock(string lockname, long timeout) { var Event = new System.Threading.ManualResetEvent(false); //get id and confirm lock exists . var node = _client.GetValAsync($"/locks/{lockname}").Result; long Id = 0; if (!long.TryParse(node, out Id)) { return(new WatchLockModel() { Id = 0, Result = WatcherResult.NotExists }); } //at etcd use single watch on lock. _client.Watch($"/locks/{lockname}", new Action <dotnet_etcd.WatchEvent[]>((e) => { foreach (var item in e) { if (item.Type == Mvccpb.Event.Types.EventType.Delete && item.Key == $"/locks/{lockname}") { Event.Set(); } } })); //timeout or unlock var action = System.Threading.WaitHandle.WaitAny(new System.Threading.WaitHandle[] { Event }, TimeSpan.FromMilliseconds(timeout)); if (action == System.Threading.WaitHandle.WaitTimeout) { return(new WatchLockModel() { Id = Id, Result = WatcherResult.TimeOuit }); } else { return(new WatchLockModel() { Id = Id, Result = WatcherResult.UnLocked }); } }