/// <summary> /// perform the operation associated with this call /// </summary> /// <param name="initEdgeName">string:: the edge to traverse</param> /// <exception cref="AbandonedMutexException" >thrown when the mutex is null</exception> /// <exception cref="InvalidOperationException" >thrown when EdgesCollection is uninitialized</exception> /// <exception cref="KeyNotFoundException" >thrown when the edge name does not exist.</exception> /// <exception cref="NullReferenceException" >thrown when the edge State is null</exception> /// <exception cref="TimeoutException" >thrown when obtaining the mutex times out</exception> public void TraverseEdgeForward(string initEdgeName) { if (_mtxEdgesCollection == null) { string exceptionMsg = $"The edge {initEdgeName} could not be retrieved because the mutex has been abanoned."; throw new AbandonedMutexException(exceptionMsg); } CheckEdgesCollection(); if (!_mtxEdgesCollection.WaitOne(_mtxTimeout)) { // timed out waiting for the mutex string exceptionMsg = $"The edge {initEdgeName} could not be retrieved because a lock could not be obtained."; throw new TimeoutException(exceptionMsg); } try { string scrubbedEdgeName = _stringUtility.ScrubName(initEdgeName); if (!EdgesCollection.ContainsKey(scrubbedEdgeName)) { throw new KeyNotFoundException($"Edge {scrubbedEdgeName} not found on Node {Name}."); } IEdge foundEdge = EdgesCollection[scrubbedEdgeName]; foundEdge.Forward(this); } finally { _mtxEdgesCollection.ReleaseMutex(); } }