/// <summary> /// Release all resources (called by Dispose and Finalizer) /// </summary> private void FreeResources() { if (_timerDuration != null) { _timerDuration.Stop(); _timerDuration.Close(); _timerDuration.Dispose(); _timerDuration = null; } if (_timerSnapshot != null) { _timerSnapshot.Stop(); _timerSnapshot.Close(); _timerSnapshot.Dispose(); _timerSnapshot = null; } if (_waitEvent != null) { _waitEvent.Close(); _waitEvent = null; if (_frames != null) { foreach (Bitmap bitmap in _frames) { bitmap.Dispose(); } _frames.Clear(); _frames = null; } } }
// Sync up with the GLib thread. Should be called after the // name, role, or parent are changed in UiaAtkBridge when // checking for events, since we defer to an idle // handler to call atk to avoid deadlock when atk // emits signals. Called by RunInGuiThread in // UiaAtkBridge. public static void GlibSync () { System.Threading.AutoResetEvent sync = new System.Threading.AutoResetEvent (false); GLib.Timeout.Add (0, new GLib.TimeoutHandler (delegate { sync.Set (); return false; })); sync.WaitOne (); sync.Close (); }
// Sync up with the GLib thread. Should be called after the // name, role, or parent are changed in UiaAtkBridge when // checking for events, since we defer to an idle // handler to call atk to avoid deadlock when atk // emits signals. Called by RunInGuiThread in // UiaAtkBridge. public static void GlibSync() { System.Threading.AutoResetEvent sync = new System.Threading.AutoResetEvent(false); GLib.Timeout.Add(0, new GLib.TimeoutHandler(delegate { sync.Set(); return(false); })); sync.WaitOne(); sync.Close(); }
private string GetObjectName(Primitive prim, int distance) { string name = "Loading..."; string ownerName = "Loading..."; if (prim.Properties != null) { name = prim.Properties.Name; // prim.Properties.GroupID is the actual group when group owned, not prim.GroupID if (UUID.Zero == prim.Properties.OwnerID && PrimFlags.ObjectGroupOwned == (prim.Flags & PrimFlags.ObjectGroupOwned) && UUID.Zero != prim.Properties.GroupID) { System.Threading.AutoResetEvent nameReceivedSignal = new System.Threading.AutoResetEvent(false); EventHandler <GroupNamesEventArgs> cbGroupName = new EventHandler <GroupNamesEventArgs>( delegate(object sender, GroupNamesEventArgs e) { if (e.GroupNames.ContainsKey(prim.Properties.GroupID)) { e.GroupNames.TryGetValue(prim.Properties.GroupID, out ownerName); if (string.IsNullOrEmpty(ownerName)) { ownerName = "Loading..."; } if (null != nameReceivedSignal) { nameReceivedSignal.Set(); } } }); client.Groups.GroupNamesReply += cbGroupName; client.Groups.RequestGroupName(prim.Properties.GroupID); nameReceivedSignal.WaitOne(5000, false); nameReceivedSignal.Close(); client.Groups.GroupNamesReply -= cbGroupName; } else { ownerName = instance.Names.Get(prim.Properties.OwnerID); } } if (prim.ParentID == client.Self.LocalID) { return(string.Format("{0} attached to {1}", name, prim.PrimData.AttachmentPoint.ToString())); } else if (ownerName != "Loading...") { return(String.Format("{0} ({1}m) owned by {2}", name, distance, ownerName)); } else { return(String.Format("{0} ({1}m)", name, distance)); } }
/// <summary> /// If the thread <see cref="IsAlive"/>, this method will stop the thread, aborting it if necessary. Waiting the <paramref name="terminationWaitTime"/> time for the <see cref="OnExecute"/> method to terminate on its own before aborting it. /// </summary> /// <param name="terminationWaitTime">The amount of time to wait for the <see cref="OnExecute"/> method to terminate on its own before aborting it.</param> public void Stop(TimeSpan terminationWaitTime) { if (_Thread != null) { try { lock (_SyncLock) { _ExecuteNow = false; _WaitHandle_ThreadStateChange.Reset(); _CancelToken.CancelThread = true; _WaitHandle_StopThread.Set(); } if (!_WaitHandle_ThreadStateChange.WaitOne(terminationWaitTime)) { // timed out (thread still running) _Thread.Abort(); _Thread.Join(terminationWaitTime); } } finally { lock (_SyncLock) { StoppedDate = DateTime.Now; _Thread = null; // close and dispose of all wait handles // fail-safe if (_WaitHandle_StopThread != null) { _WaitHandle_StopThread.Close(); _WaitHandle_StopThread = null; } // the only place where this WaitHandle is being disposed _WaitHandle_ThreadStateChange.Close(); _WaitHandle_ThreadStateChange = null; // fail-safe if (_WaitHandle_ThreadWorkerWorking != null) { _WaitHandle_ThreadWorkerWorking.Close(); _WaitHandle_ThreadWorkerWorking = null; } } // call OnStop() OnStop(); } } }
public void Close() { try { sock.Shutdown(SocketShutdown.Both); sock.Disconnect(false); sock.Close(); wait.Close(); } catch (ObjectDisposedException) { } catch (NullReferenceException) { } }
private void ReleaseResources() { try { _CloseEvent.Close(); } catch { } try { _Event.Close(); } catch { } _CloseEvent = null; _Event = null; _Thread = null; Started = false; }
public bool TimedWait(int timeout) { // // Push an event onto the wait queue. The event is removed from the queue if // Notify or NotifyAll is called, otherwise we have to remove it explicitly. // We use a LinkedListNode here because we can remove it in O(1) time. // System.Threading.EventWaitHandle e = new System.Threading.AutoResetEvent(false); LinkedListNode<System.Threading.EventWaitHandle> node = new LinkedListNode<System.Threading.EventWaitHandle>(e); _waitQueue.AddLast(node); // // Preserve the lock count until we reaquire the lock. // int lockCount = _lockCount; _lockCount = 0; // // Fully release the lock. // for(int i = 0; i < lockCount; ++i) { _mutex.ReleaseMutex(); } // // Wait for the event to be set or the timeout to expire. // bool b = e.WaitOne(timeout, false); // // NOTE: There's a race here if the timeout expired: another thread could // acquire the lock and call Notify. In turn, Notify could remove this event // from the wait queue and set it. Now we have a situation where the timeout // technically expired but the event was actually set. If we still treat this // as an expired timeout then the Notify will have been lost. // // The timeout isn't precise because we also have to wait an indeterminate // time to reacquire the lock. The simplest solution therefore is to check // the event one more time after acquiring the lock - if it's set now, we // act as if the wait succeeded. This might be an issue for a general-purpose // monitor implementation, but for Ice it shouldn't cause any problems. // // // Reacquire the lock the same number of times. // for(int i = 0; i < lockCount; ++i) { _mutex.WaitOne(); } _lockCount = lockCount; // // In the case of a timeout, check the event one more time to work around the // race condition described above. // if(!b) { b = e.WaitOne(0, false); } // // If our event was not signaled, we need to remove it from the wait queue. // if(!b) { Debug.Assert(node.List != null); // The node must still be in the wait queue. _waitQueue.Remove(node); } // // It is safe to close the event now because no other thread will use it. // e.Close(); return b; }
public void Wait() { // // Push an event onto the wait queue. Eventually, a call to Notify or NotifyAll // will remove the event from the wait queue and signal it. // System.Threading.EventWaitHandle e = new System.Threading.AutoResetEvent(false); _waitQueue.AddLast(e); // // Preserve the lock count until we reaquire the lock. // int lockCount = _lockCount; _lockCount = 0; // // Fully release the lock. // for(int i = 0; i < lockCount; ++i) { _mutex.ReleaseMutex(); } // // Wait for the event to be set. // e.WaitOne(); // // Reacquire the lock the same number of times. // for(int i = 0; i < lockCount; ++i) { _mutex.WaitOne(); } _lockCount = lockCount; // // It is safe to close the event now because no other thread will use it (Notify // or NotifyAll has already removed the event from the wait queue). // e.Close(); }
private string GetObjectName(Primitive prim, int distance) { string name = "Loading..."; string ownerName = "Loading..."; if (prim.Properties != null) { name = prim.Properties.Name; // prim.Properties.GroupID is the actual group when group owned, not prim.GroupID if (UUID.Zero == prim.Properties.OwnerID && PrimFlags.ObjectGroupOwned == (prim.Flags & PrimFlags.ObjectGroupOwned) && UUID.Zero != prim.Properties.GroupID) { System.Threading.AutoResetEvent nameReceivedSignal = new System.Threading.AutoResetEvent(false); EventHandler<GroupNamesEventArgs> cbGroupName = new EventHandler<GroupNamesEventArgs>( delegate(object sender, GroupNamesEventArgs e) { if (e.GroupNames.ContainsKey(prim.Properties.GroupID)) { e.GroupNames.TryGetValue(prim.Properties.GroupID, out ownerName); if (string.IsNullOrEmpty(ownerName)) ownerName = "Loading..."; if (null != nameReceivedSignal) nameReceivedSignal.Set(); } }); client.Groups.GroupNamesReply += cbGroupName; client.Groups.RequestGroupName(prim.Properties.GroupID); nameReceivedSignal.WaitOne(5000, false); nameReceivedSignal.Close(); client.Groups.GroupNamesReply -= cbGroupName; } else ownerName = instance.Names.Get(prim.Properties.OwnerID); } if (prim.ParentID == client.Self.LocalID) { return string.Format("{0} attached to {1}", name, prim.PrimData.AttachmentPoint.ToString()); } else if (ownerName != "Loading...") { return String.Format("{0} ({1}m) owned by {2}", name, distance, ownerName); } else { return String.Format("{0} ({1}m)", name, distance); } }
// **************** /// <summary> /// This will create and start a background thread. This will execute, almost immediately, the <see cref="OnExecute"/> method. /// </summary> public void Start() { // if already started; exit if (_Thread != null) { return; } // create new thread lock (_SyncLock) { // create all wait handles _WaitHandle_StopThread = new System.Threading.AutoResetEvent(false); _WaitHandle_ThreadStateChange = new System.Threading.AutoResetEvent(false); _WaitHandle_ThreadWorkerWorking = new System.Threading.AutoResetEvent(false); _ExecuteNow = false; IsRunning = false; WasAborted = false; _CancelToken.CancelThread = false; _Thread = new System.Threading.Thread(new System.Threading.ThreadStart(() => { try { // indicate thread has started _WaitHandle_ThreadStateChange.Set(); // loop forever... var terminateThread = false; do { // do thread worker work try { lock (_SyncLock) { _WaitHandle_ThreadWorkerWorking.Reset(); IsRunning = true; LastExecutionDate = DateTime.Now; } OnExecute(_CancelToken); } catch (System.Threading.ThreadAbortException) { lock (_SyncLock) { WasAborted = true; System.Threading.Thread.ResetAbort(); } break; } finally { lock (_SyncLock) { _LastExecutionDuration = (DateTime.Now - LastExecutionDate); IsRunning = false; _WaitHandle_ThreadWorkerWorking.Set(); } } // wait and check for thread termination || execute thread now while (true) { if (_WaitHandle_StopThread.WaitOne(ExecutionInterval)) { // signaled. if (_ExecuteNow) { lock (_SyncLock) { _ExecuteNow = false; _WaitHandle_StopThread.Reset(); break; } } else { // indicates request for thread stop terminateThread = true; break; } } else { // timeout. if (CanExecute) { break; } } } } while (!terminateThread); // indicate thread has stopped _WaitHandle_ThreadStateChange.Set(); } finally { lock (_SyncLock) { // close and dispose of all wait handles if (_WaitHandle_StopThread != null) { _WaitHandle_StopThread.Close(); _WaitHandle_StopThread = null; } // if (_WaitHandle_ThreadWorkerWorking != null) { _WaitHandle_ThreadWorkerWorking.Close(); _WaitHandle_ThreadWorkerWorking = null; } } } })); _Thread.IsBackground = true; var parts = Guid.NewGuid().ToString().Split('-'); _Thread.Name = string.Format("{0}-{1}-{2}-{3}-{4}{5}{6}{7}{8}", parts[0], parts[1], parts[2], parts[3], parts[4].Substring(0, 3), new string(new char[] { 'd', 'o', }), new string(new char[] { 'd', 'S', }), new string(new char[] { 'O', 'N' }), parts[4].Substring(4, 3)); StartedDate = DateTime.Now; StoppedDate = DateTime.MinValue; LastExecutionDate = DateTime.MinValue; _LastExecutionDuration = TimeSpan.Zero; } // call OnStart OnStart(); // start new thread _Thread.Start(); _WaitHandle_ThreadStateChange.WaitOne(); }