public void Dispose() { if (_disposed) { return; } _disposed = true; _registeredWaitHandle?.Unregister(null); _handle?.Dispose(); _registeredWaitHandle = null; _handle = null; }
public static Task <bool> WaitForProcessExitAsync(uint pid) { void *hProcess = OpenProcess(SYNCHRONIZE, 0, pid); if (hProcess == null) { return(Task.FromResult(false)); } var tasker = new TaskCompletionSource <bool>(); var hProcessSafe = new NativeWaitHandle(hProcess, true); RegisteredWaitHandle registered = null; WaitOrTimerCallback λHappened = (state, timeout) => { hProcessSafe.Close(); #pragma warning disable once AccessToModifiedClosure registered?.Unregister(null); tasker.SetResult(true); }; registered = ThreadPool.RegisterWaitForSingleObject(hProcessSafe, λHappened, Missing.Value, -1, true); return(tasker.Task); }
private void OnComplete() { Event.Remove(ref removedFromManager); registeredWaitHandle?.Unregister(waitHandle); Interface.Oxide.NextTick(() => { if (request == null) { return; } request = null; Owner?.TrackStart(); try { Callback(ResponseCode, ResponseText); } catch (Exception ex) { var message = "Web request callback raised an exception"; if (Owner && Owner != null) { message += $" in '{Owner.Name} v{Owner.Version}' plugin"; } Interface.Oxide.LogException(message, ex); } Owner?.TrackEnd(); Owner = null; }); }
public static async Task <bool> WaitOneAsync(this WaitHandle wh, int millisecondsTimeout = -1, CancellationToken?ct = null) { RegisteredWaitHandle rwh = null; CancellationTokenRegistration?ctr = null; try { var tcs = new TaskCompletionSource <bool>(); rwh = ThreadPool.RegisterWaitForSingleObject(wh, (s, t) => ((TaskCompletionSource <bool>)s).TrySetResult(!t), tcs, millisecondsTimeout, true); ctr = ct?.Register(s => ((TaskCompletionSource <bool>)s).TrySetCanceled(), tcs); return(await tcs.Task); } finally { rwh?.Unregister(null); ctr?.Dispose(); } }
// http://stackoverflow.com/questions/25382583/waiting-on-a-named-semaphore-with-waitone100-vs-waitone0-task-delay100 // http://blog.nerdbank.net/2011/07/c-await-for-waithandle.html // F# has a AwaitWaitHandle method that accepts a time out... and seems pretty complex... // version below should be OK public static Task WaitOneAsync(this WaitHandle handle, int millisecondsTimeout = Timeout.Infinite) { var tcs = new TaskCompletionSource <object?>(); var callbackHandleInitLock = new object(); lock (callbackHandleInitLock) { RegisteredWaitHandle?callbackHandle = null; // ReSharper disable once RedundantAssignment callbackHandle = ThreadPool.RegisterWaitForSingleObject( handle, (state, timedOut) => { //TODO: We aren't checking if this is timed out tcs.SetResult(null); // we take a lock here to make sure the outer method has completed setting the local variable callbackHandle. lock (callbackHandleInitLock) { // ReSharper disable once PossibleNullReferenceException // ReSharper disable once AccessToModifiedClosure callbackHandle?.Unregister(null); } }, /*state:*/ null, /*millisecondsTimeOutInterval:*/ millisecondsTimeout, /*executeOnlyOnce:*/ true); } return(tcs.Task); }
/// <summary> /// Waits for a signal asynchronously on the provided <paramref name="handle"/>. /// </summary> /// <param name="handle">The handle to wait on.</param> /// <param name="timeout">The timeout in milliseconds. This parameter is optional. /// <br/>Default value: <see cref="Timeout.Infinite">Timeout.Infinite</see></param> /// <param name="cancellationToken">A token for cancellation. This parameter is optional. /// <br/>Default value: <see cref="CancellationToken.None">CancellationToken.None</see></param> /// <returns><see langword="true"/>, if the specified <paramref name="handle"/> receives a signal before timing out or canceling; otherwise, <see langword="false"/>.</returns> public static async Task <bool> WaitOneAsync(this WaitHandle handle, int timeout = Timeout.Infinite, CancellationToken cancellationToken = default) { if (handle == null) { Throw.ArgumentNullException(Argument.handle); } if (cancellationToken.IsCancellationRequested) { return(false); } RegisteredWaitHandle registeredHandle = null; var tokenRegistration = default(CancellationTokenRegistration); try { var completionSource = new TaskCompletionSource <bool>(); registeredHandle = ThreadPool.RegisterWaitForSingleObject(handle, (state, timedOut) => ((TaskCompletionSource <bool>)state).TrySetResult(!timedOut), completionSource, timeout, true); tokenRegistration = cancellationToken.Register(state => ((TaskCompletionSource <bool>)state).TrySetResult(false), completionSource); return(await completionSource.Task.ConfigureAwait(false)); } finally { registeredHandle?.Unregister(null); tokenRegistration.Dispose(); } }
/// <summary> /// Creates a Task that is marked as completed when the specified <see cref="WaitHandle"/> is signaled. /// </summary> /// <param name="handle">The handle whose signal triggers the task to be completed.</param> /// <returns>A Task that is completed after the handle is signaled.</returns> /// <remarks> /// There is a (brief) time delay between when the handle is signaled and when the task is marked as completed. /// </remarks> public static Task ToTask(this WaitHandle handle) { Contract.Requires <ArgumentNullException>(handle != null); Contract.Ensures(Contract.Result <Task>() != null); var tcs = new TaskCompletionSource <object>(); var localVariableInitLock = new object(); lock (localVariableInitLock) { RegisteredWaitHandle callbackHandle = null; void Callback(object state, bool timedOut) { tcs.SetResult(null); lock (localVariableInitLock) { // We take a lock here to make sure the outer method // has completed setting the local variable callbackHandle. // ReSharper disable once AccessToModifiedClosure callbackHandle?.Unregister(null); } } callbackHandle = ThreadPool.RegisterWaitForSingleObject(handle, Callback, null, Timeout.Infinite, true); } return(tcs.Task); }
/// <summary> /// Async version of WaitOne taken from the following blog: /// https://thomaslevesque.com/2015/06/04/async-and-cancellation-support-for-wait-handles/ /// </summary> public static async Task <bool> WaitOneAsync(this WaitHandle objHandle, int intTimeout, CancellationToken token = default) { token.ThrowIfCancellationRequested(); RegisteredWaitHandle objRegisteredHandle = null; CancellationTokenRegistration objTokenRegistration = default; try { TaskCompletionSource <bool> objTaskCompletionSource = new TaskCompletionSource <bool>(); objRegisteredHandle = ThreadPool.RegisterWaitForSingleObject( objHandle, (objState, blnTimedOut) => ((TaskCompletionSource <bool>)objState).TrySetResult(!blnTimedOut), objTaskCompletionSource, intTimeout, true); objTokenRegistration = token.Register( objState => ((TaskCompletionSource <bool>)objState).TrySetCanceled(token), objTaskCompletionSource); return(await objTaskCompletionSource.Task); } finally { objRegisteredHandle?.Unregister(null); objTokenRegistration.Dispose(); } }
public static async Task <bool> WaitOneAsync(this WaitHandle handle, int millisecondsTimeout, CancellationToken cancellationToken) { RegisteredWaitHandle registeredHandle = null; CancellationTokenRegistration tokenRegistration = default; try { var tcs = new TaskCompletionSource <bool>(); registeredHandle = ThreadPool.RegisterWaitForSingleObject( handle, (state, timedOut) => ((TaskCompletionSource <bool>)state).TrySetResult(!timedOut), tcs, millisecondsTimeout, true); tokenRegistration = cancellationToken.Register( state => ((TaskCompletionSource <bool>)state).TrySetCanceled(), tcs); return(await tcs.Task); } finally { registeredHandle?.Unregister(null); tokenRegistration.Dispose(); } }
private async Task <T> InvokeAsync <T>( Delegate invokeDelegate, TimeSpan timeOutSpan = default, CancellationToken cancellationToken = default, params object[] args) { var tokenRegistration = default(CancellationTokenRegistration); RegisteredWaitHandle?registeredWaitHandle = null; try { TaskCompletionSource <bool> taskCompletionSource = new(); IAsyncResult?asyncResult = BeginInvoke(invokeDelegate, args); registeredWaitHandle = ThreadPool.RegisterWaitForSingleObject( asyncResult.AsyncWaitHandle, new WaitOrTimerCallback(InvokeAsyncCallBack), taskCompletionSource, timeOutSpan.Milliseconds, true); tokenRegistration = cancellationToken.Register( CancellationTokenRegistrationCallBack, taskCompletionSource); await taskCompletionSource.Task; object?returnObject = EndInvoke(asyncResult); return((T)returnObject); } finally { registeredWaitHandle?.Unregister(null); tokenRegistration.Dispose(); }
// Reference: ASYNC AND CANCELLATION SUPPORT FOR WAIT HANDLES // https://thomaslevesque.com/2015/06/04/async-and-cancellation-support-for-wait-handles/ internal static async Task <bool> WaitOneAsync(this WaitHandle handle, int millisecondsTimeout, CancellationToken cancellationToken) { if (handle == null) { throw new ArgumentNullException($"{nameof(handle)} is null"); } RegisteredWaitHandle? registeredHandle = null; CancellationTokenRegistration tokenRegistration = default; try { var tcs = new TaskCompletionSource <bool>(); registeredHandle = ThreadPool.RegisterWaitForSingleObject( handle, (state, timedOut) => ((TaskCompletionSource <bool>)state).TrySetResult(!timedOut), tcs, millisecondsTimeout, true); tokenRegistration = cancellationToken.Register( state => ((TaskCompletionSource <bool>)state).TrySetCanceled(), tcs); return(await tcs.Task.ConfigureAwait(false)); } finally { registeredHandle?.Unregister(null); tokenRegistration.Dispose(); } }
public IRegisteredCallback Create(WaitOrTimerCallback callback, object state) { if (callback == null) { throw new ArgumentNullException(nameof(callback)); } AutoResetEvent waitEvent = null; try { waitEvent = new AutoResetEvent(false); RegisteredWaitHandle waitHandle = null; try { waitHandle = ThreadPool.RegisterWaitForSingleObject(waitEvent, callback, state, Timeout.Infinite, false); return(new RegisteredCallback( waitEvent, waitHandle)); } catch (Exception) { waitHandle?.Unregister(waitEvent); throw; } } catch (Exception) { waitEvent?.Dispose(); throw; } }
protected override void Dispose(bool disposing) { if (disposing) { timerHandle?.Unregister(null); refreshEvent.Dispose(); } base.Dispose(disposing); }
/// <summary> /// Allows awaiting a <see cref="WaitHandle"/> which /// <inheritdoc cref="WaitHandle"/> /// </summary> /// <param name="handle">The <see cref="WaitHandle"/> to await.</param> /// <param name="timeout">The timeout period in milliseconds to return false if timed out. /// <code> /// // In order to use timeouts and infinitely wait till a resource is free use /// (int)timeout.Infinite /// </code></param> /// <param name="token">The cancellation token to use to throw a <see cref="TaskCanceledException"/> /// if this token gets cancelled</param> /// <returns>True if the handle is free, false if it is not</returns> /// <exception cref="TaskCanceledException">Throws if the cancellation token is invoked</exception> /// <example> /// handle.WaitHandleAsync((int)Timeout.Infinite, cancellationToken); /// </example> public static async Task <bool> WaitHandleAsync(this WaitHandle handle, int timeout, CancellationToken?token) { // Create a handle that awaits the original wait handle RegisteredWaitHandle registeredWaitHandle = null; // Store the token CancellationTokenRegistration?tokenRegistration = null; try { // Create a new task completion source to await TaskCompletionSource <bool> taskCompletionSource = new TaskCompletionSource <bool>(); /* Use RegisterWaitForSingleObject so we get a callback * once the wait handle has finished, and set the taskCompletionSource result in that callback. */ registeredWaitHandle = ThreadPool.RegisterWaitForSingleObject( // The handle to wait handle, // When it is finished, set the taskCompletionSource (state, timedOut) => ((TaskCompletionSource <bool>)state) .TrySetResult(!timedOut), // Pass the taskCompletion source as the state so we don't have a reference to the parent // taskCompletionSource (optimization) taskCompletionSource, // Set timeout if passed in timeout, // Run once don't keep resetting timeout true); /* * Register to run the action and set the taskCompletionSource as cancelled * if the cancellation token itself is cancelled; which will throw a TaskCancelledException * up to the caller. */ if (token.HasValue) { tokenRegistration = token.Value.Register((state) => ((TaskCompletionSource <bool>)state) .TrySetCanceled(), taskCompletionSource); } // Await the handle or the cancellation token return(await taskCompletionSource.Task); } finally { // Clean up registered wait handle registeredWaitHandle?.Unregister(null); // Dispose of the token we had to create to register for the cancellation token callback tokenRegistration?.DisposeAsync(); } }
/// <summary> /// 检查线程池的方法 /// </summary> /// <param name="state"></param> /// <param name="timeout"></param> private static void CheckThreadPool(object?state, bool timeout) { ThreadPool.GetAvailableThreads(out var workerThreads, out _); ThreadPool.GetMaxThreads(out var maxWordThreads, out _); System.Diagnostics.Debug.WriteLine($"现在是{DateTime.Now},可用线程数为{workerThreads},最大线程数为{maxWordThreads}"); //当可用的线数与池程池最大的线程相等时表示线程池中所有的线程已经完成 if (workerThreads == maxWordThreads) { //当执行此方法后CheckThreadPool将不再执行 _rhw?.Unregister(null); //此处加入所有线程完成后的处理代码 System.Diagnostics.Debug.WriteLine("所有线程结束!"); ThreadPoolEndFlag = true; } }
internal static async Task <bool> WaitOneAsync(this WaitHandle handle, int millisecondsTimeout, CancellationToken token) { RegisteredWaitHandle registeredHandle = null; var tokenRegistration = default(CancellationTokenRegistration); try { var tcs = new TaskCompletionSource <bool>(); registeredHandle = ThreadPool.RegisterWaitForSingleObject( handle, (s, t) => { var val = (Tuple <TaskCompletionSource <bool>, CancellationToken>)s; //In Release builds, there is a race condition between the CancellationTokenSource //callback and the ManualResetToken.Set() callback. To mitigate this, if the //waithandle Set() callback is called first, we also check whether we need to perform //the work of the CancellationTokenSource callback. When the CancellationTokenSource callback //is finally called, it will return false as it always does, due to TrySetResult already //having been called. if (val.Item2.IsCancellationRequested) { val.Item1.TrySetCanceled(); } val.Item1.TrySetResult(!t); }, Tuple.Create(tcs, token), millisecondsTimeout, true ); tokenRegistration = token.Register( s => ((TaskCompletionSource <bool>)s).TrySetCanceled(), tcs ); return(await tcs.Task.ConfigureAwait(false)); } finally { registeredHandle?.Unregister(null); tokenRegistration.Dispose(); } }
/// <summary> /// Allows awaiting a <see cref="WaitHandle"/> /// </summary> /// <param name="handle">The handle to await</param> /// <param name="millisecondsTimeout">The timeout period to return false if timed out</param> /// <param name="cancellationToken">The cancellation token to use to throw a <see cref="TaskCanceledException"/> if this token gets canceled</param> /// <returns>Returns true if the handle is free, false if it is not</returns> /// <exception cref="TaskCanceledException">Throws if the cancellation token is canceled</exception> public static async Task <bool> WaitOneAsync(this WaitHandle handle, int millisecondsTimeout, CancellationToken?cancellationToken) { // Create a handle that awaiting the original wait handle RegisteredWaitHandle registeredWaitHandle = null; // Store the token CancellationTokenRegistration?tokenRegistration = null; try { // Create a task completion source to await var tcs = new TaskCompletionSource <bool>(); // Use RegisterWaitForSingleObject so we get a callback // once the wait handle has finished, and set the tcs result in that callback registeredWaitHandle = ThreadPool.RegisterWaitForSingleObject( // The handle to wait on handle, // When it is finished, set the tcs result (state, timedOut) => ((TaskCompletionSource <bool>)state).TrySetResult(!timedOut), // Pass the tcs as the state so we don't have a reference to the parent tcs (optimization) tcs, // Set timeout if passed in millisecondsTimeout, // Run once don't keep resetting timeout true); // Register to run the action and set the tcs as canceled // if the cancellation token itself is canceled // which will throw a TaskCanceledException up to the caller if (cancellationToken.HasValue) { tokenRegistration = cancellationToken.Value.Register(state => ((TaskCompletionSource <bool>)state).TrySetCanceled(), tcs); } // Await the handle or the cancellation token return(await tcs.Task); } finally { // Clean up registered wait handle registeredWaitHandle?.Unregister(null); // Dispose of the token we had to create to register for the cancellation token callback tokenRegistration?.Dispose(); } }
public static async Task <bool> WaitOneAsync(this WaitHandle handle, TimeSpan timeout) { RegisteredWaitHandle registeredHandle = null; try { var tcs = new TaskCompletionSource <bool>(); registeredHandle = ThreadPool.RegisterWaitForSingleObject( handle, (state, timedOut) => ((TaskCompletionSource <bool>)state).TrySetResult(!timedOut), tcs, timeout, true); return(await tcs.Task); } finally { registeredHandle?.Unregister(null); } }
/// <summary> /// Creates a TPL Task that is marked as completed when a <see cref="WaitHandle"/> is signaled. /// </summary> /// <param name="handle">The handle whose signal triggers the task to be completed.</param> /// <param name="timeout">The amount of time to wait before timing out.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns> /// A <see cref="Task{T}"/> that is completed after the handle is signaled. The result will be /// <see langword="true"/> if the <see cref="WaitHandle"/> was triggered before <paramref name="timeout"/> /// elapses, <see langword="false"/> otherwise. /// </returns> /// <remarks> /// https://thomaslevesque.com/2015/06/04/async-and-cancellation-support-for-wait-handles/ /// https://github.com/StephenCleary/AsyncEx/blob/master/src/Nito.AsyncEx.Interop.WaitHandles/Interop/WaitHandleAsyncFactory.cs /// </remarks> public static async Task <bool> ToTask(this WaitHandle handle, TimeSpan timeout, CancellationToken cancellationToken) { Guard.IsNotNull(handle, nameof(handle)); // Handle synchronous cases. bool alreadySignaled = handle.WaitOne(0); if (alreadySignaled) { return(true); } if (timeout == TimeSpan.Zero) { return(false); } cancellationToken.ThrowIfCancellationRequested(); RegisteredWaitHandle? registeredHandle = null; CancellationTokenRegistration tokenRegistration = default; try { var tcs = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously); registeredHandle = ThreadPool.RegisterWaitForSingleObject( handle, (state, timedOut) => ((TaskCompletionSource <bool>)state !).TrySetResult(!timedOut), tcs, timeout, true); tokenRegistration = cancellationToken.Register(state => ((TaskCompletionSource <bool>)state !).TrySetCanceled(), tcs); return(await tcs.Task.ConfigureAwait(false)); } finally { registeredHandle?.Unregister(null); tokenRegistration.Dispose(); } }
/// <summary> /// Asynchronously waits for the wait handle. /// </summary> /// <param name="handle">The handle.</param> /// <param name="timeout">The timeout.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns><c>true</c> if the timeout has not been reached, <c>false</c> otherwise.</returns> public static async ValueTask <bool> WaitOneAsync( this WaitHandle handle, TimeSpan timeout, CancellationToken cancellationToken) { RegisteredWaitHandle? registeredHandle = null; CancellationTokenRegistration tokenRegistration = default; try { var tcs = new TaskCompletionSource <bool>(); registeredHandle = ThreadPool.RegisterWaitForSingleObject( handle, ( state, timedOut) => ((TaskCompletionSource <bool>)state !).TrySetResult(!timedOut), tcs, timeout, true); tokenRegistration = cancellationToken.Register( state => state.TrySetCanceled(), tcs); return(await tcs.Task); } finally { registeredHandle?.Unregister(null); #if NETSTANDARD21_OR_GREATER await tokenRegistration.DisposeAsync(); #else tokenRegistration.Dispose(); #endif } }
void IDisposable.Dispose() => _registeredWaitHandle.Unregister(null);
static Stream EndGetRequestStreamWithTimeout (HttpWebRequest request, IAsyncResult asyncResult, RegisteredWaitHandle handle) { try { handle.Unregister (asyncResult.AsyncWaitHandle); return request.EndGetRequestStream (asyncResult); } catch (WebException ex) { if (ex.Status == WebExceptionStatus.RequestCanceled) { throw new WebException ("GetRequestStream operation has timed out.", WebExceptionStatus.Timeout); } throw; } }
internal static void WriteToSync <T>(this Stream stream, Stream toStream, long?copyLength, long?maxLength, bool calculateMd5, bool syncRead, ExecutionState <T> executionState, StreamDescriptor streamCopyState) { if (copyLength.HasValue && maxLength.HasValue) { throw new ArgumentException(SR.StreamLengthMismatch); } if (stream.CanSeek && maxLength.HasValue && stream.Length - stream.Position > maxLength) { throw new InvalidOperationException(SR.StreamLengthError); } if (stream.CanSeek && copyLength.HasValue && stream.Length - stream.Position < copyLength) { throw new ArgumentOutOfRangeException("copyLength", SR.StreamLengthShortError); } byte[] buffer = new byte[GetBufferSize(stream)]; if (streamCopyState != null && calculateMd5 && streamCopyState.Md5HashRef == null) { streamCopyState.Md5HashRef = new MD5Wrapper(); } RegisteredWaitHandle waitHandle = null; ManualResetEvent completedEvent = null; if (!syncRead && executionState.OperationExpiryTime.HasValue) { completedEvent = new ManualResetEvent(false); waitHandle = ThreadPool.RegisterWaitForSingleObject( completedEvent, StreamExtensions.MaximumCopyTimeCallback <T>, executionState, executionState.RemainingTimeout, true); } try { long?bytesRemaining = copyLength; int readCount; do { if (executionState.OperationExpiryTime.HasValue && DateTime.Now.CompareTo(executionState.OperationExpiryTime.Value) > 0) { throw Exceptions.GenerateTimeoutException(executionState.Cmd != null ? executionState.Cmd.CurrentResult : null, null); } // Determine how many bytes to read this time so that no more than copyLength bytes are read int bytesToRead = MinBytesToRead(bytesRemaining, buffer.Length); if (bytesToRead == 0) { break; } // Read synchronously or asynchronously readCount = syncRead ? stream.Read(buffer, 0, bytesToRead) : stream.EndRead(stream.BeginRead(buffer, 0, bytesToRead, null /* Callback */, null /* State */)); // Decrement bytes to write from bytes read if (bytesRemaining.HasValue) { bytesRemaining -= readCount; } // Write if (readCount > 0) { toStream.Write(buffer, 0, readCount); // Update the StreamDescriptor after the bytes are successfully committed to the output stream if (streamCopyState != null) { streamCopyState.Length += readCount; if (maxLength.HasValue && streamCopyState.Length > maxLength.Value) { throw new InvalidOperationException(SR.StreamLengthError); } if (streamCopyState.Md5HashRef != null) { streamCopyState.Md5HashRef.UpdateHash(buffer, 0, readCount); } } } }while (readCount != 0); if (bytesRemaining.HasValue && bytesRemaining != 0) { throw new ArgumentOutOfRangeException("copyLength", SR.StreamLengthShortError); } } catch (Exception) { if (executionState.OperationExpiryTime.HasValue && DateTime.Now.CompareTo(executionState.OperationExpiryTime.Value) > 0) { throw Exceptions.GenerateTimeoutException(executionState.Cmd != null ? executionState.Cmd.CurrentResult : null, null); } else { throw; } } finally { if (waitHandle != null) { waitHandle.Unregister(null); } if (completedEvent != null) { completedEvent.Close(); } } if (streamCopyState != null && streamCopyState.Md5HashRef != null) { streamCopyState.Md5 = streamCopyState.Md5HashRef.ComputeHash(); streamCopyState.Md5HashRef = null; } }
public static void BlockingUnregister() { RegisteredWaitHandle handle = ThreadPool.RegisterWaitForSingleObject(new AutoResetEvent(false), (_, __) => {}, null, ThreadTestHelpers.UnexpectedTimeoutMilliseconds, true); handle.Unregister(new InvalidWaitHandle()); }
public static void QueueRegisterPositiveAndFlowTest() { var asyncLocal = new AsyncLocal <int>(); asyncLocal.Value = 1; var obj = new object(); var registerWaitEvent = new AutoResetEvent(false); var threadDone = new AutoResetEvent(false); RegisteredWaitHandle registeredWaitHandle = null; Exception backgroundEx = null; int backgroundAsyncLocalValue = 0; Action <bool, Action> commonBackgroundTest = (isRegisteredWaitCallback, test) => { try { if (isRegisteredWaitCallback) { RegisteredWaitHandle toUnregister = registeredWaitHandle; registeredWaitHandle = null; Assert.True(toUnregister.Unregister(threadDone)); } test(); backgroundAsyncLocalValue = asyncLocal.Value; } catch (Exception ex) { backgroundEx = ex; } finally { if (!isRegisteredWaitCallback) { threadDone.Set(); } } }; Action <bool> waitForBackgroundWork = isWaitForRegisteredWaitCallback => { if (isWaitForRegisteredWaitCallback) { registerWaitEvent.Set(); } threadDone.CheckedWait(); if (backgroundEx != null) { throw new AggregateException(backgroundEx); } }; ThreadPool.QueueUserWorkItem( state => { commonBackgroundTest(false, () => { Assert.Same(obj, state); }); }, obj); waitForBackgroundWork(false); Assert.Equal(1, backgroundAsyncLocalValue); ThreadPool.UnsafeQueueUserWorkItem( state => { commonBackgroundTest(false, () => { Assert.Same(obj, state); }); }, obj); waitForBackgroundWork(false); Assert.Equal(0, backgroundAsyncLocalValue); registeredWaitHandle = ThreadPool.RegisterWaitForSingleObject( registerWaitEvent, (state, timedOut) => { commonBackgroundTest(true, () => { Assert.Same(obj, state); Assert.False(timedOut); }); }, obj, UnexpectedTimeoutMilliseconds, false); waitForBackgroundWork(true); Assert.Equal(1, backgroundAsyncLocalValue); registeredWaitHandle = ThreadPool.UnsafeRegisterWaitForSingleObject( registerWaitEvent, (state, timedOut) => { commonBackgroundTest(true, () => { Assert.Same(obj, state); Assert.False(timedOut); }); }, obj, UnexpectedTimeoutMilliseconds, false); waitForBackgroundWork(true); Assert.Equal(0, backgroundAsyncLocalValue); }
/// <summary> /// Creates a task that will complete after a time delay. /// </summary> /// <remarks> /// If the cancellation token is signaled before the specified time delay, then the task /// is completed in <see cref="TaskStatus.Canceled"/> state. Otherwise, the task is /// completed in <see cref="TaskStatus.RanToCompletion"/> state once the specified time /// delay has expired. /// <para>This method ignores any fractional milliseconds when evaluating <paramref name="delay"/>.</para> /// </remarks> /// <param name="delay">The time span to wait before completing the returned task</param> /// <param name="cancellationToken">The cancellation token that will be checked prior to completing the returned task</param> /// <returns>A task that represents the time delay</returns> /// <exception cref="ArgumentOutOfRangeException">If <paramref name="delay"/> represents a negative time interval.</exception> /// <exception cref="TaskCanceledException">If the task has been canceled.</exception> /// <exception cref="ObjectDisposedException">If the provided <paramref name="cancellationToken"/> has already been disposed.</exception> public static Task Delay(TimeSpan delay, CancellationToken cancellationToken) { #if NET45PLUS return(Task.Delay(delay, cancellationToken)); #else long totalMilliseconds = (long)delay.TotalMilliseconds; if (totalMilliseconds < 0) { throw new ArgumentOutOfRangeException("delay"); } if (cancellationToken.IsCancellationRequested) { return(CompletedTask.Canceled()); } if (totalMilliseconds == 0) { return(CompletedTask.Default); } TaskCompletionSource <VoidResult> result = new TaskCompletionSource <VoidResult>(); #if !PORTABLE TaskCompletionSource <VoidResult> intermediateResult = new TaskCompletionSource <VoidResult>(); RegisteredWaitHandle timerRegisteredWaitHandle = null; RegisteredWaitHandle cancellationRegisteredWaitHandle = null; WaitOrTimerCallback timedOutCallback = (object state, bool timedOut) => { if (timedOut) { intermediateResult.TrySetResult(default(VoidResult)); } }; IAsyncResult asyncResult = intermediateResult.Task; timerRegisteredWaitHandle = ThreadPool.RegisterWaitForSingleObject(asyncResult.AsyncWaitHandle, timedOutCallback, null, delay, true); if (cancellationToken.CanBeCanceled) { WaitOrTimerCallback cancelledCallback = (object state, bool timedOut) => { if (cancellationToken.IsCancellationRequested) { intermediateResult.TrySetCanceled(); } }; cancellationRegisteredWaitHandle = ThreadPool.RegisterWaitForSingleObject(cancellationToken.WaitHandle, cancelledCallback, null, Timeout.Infinite, true); } intermediateResult.Task .ContinueWith( _ => { if (cancellationRegisteredWaitHandle != null) { cancellationRegisteredWaitHandle.Unregister(null); } if (timerRegisteredWaitHandle != null) { timerRegisteredWaitHandle.Unregister(null); } }, TaskContinuationOptions.ExecuteSynchronously) .ContinueWith( cleanupTask => { switch (cleanupTask.Status) { case TaskStatus.RanToCompletion: result.SetFromTask(intermediateResult.Task); break; case TaskStatus.Canceled: result.SetCanceled(); break; case TaskStatus.Faulted: result.SetException(cleanupTask.Exception.InnerExceptions); break; default: throw new InvalidOperationException("Unreachable"); } }); #else // Since portable-net40 doesn't provide Task.Delay and also doesn't provide ThreadPool.RegisterWaitForSingleObject, // we need to implement this functionality using timers stored in a ConditionalWeakTable, which are associated with // the actual Task instance that gets returned by this method. CancellationTokenRegistration cancellationTokenRegistration = default(CancellationTokenRegistration); Timer timer = null; TimerCallback timerCallback = state => { result.TrySetResult(default(VoidResult)); timer.Dispose(); cancellationTokenRegistration.Dispose(); }; timer = new Timer(timerCallback, null, Timeout.Infinite, Timeout.Infinite); _delayTimers.Add(result.Task, timer); timer.Change(delay, TimeSpan.FromMilliseconds(-1)); if (cancellationToken.CanBeCanceled) { Action cancellationCallback = () => { result.TrySetCanceled(); if (timer != null) { timer.Dispose(); } cancellationTokenRegistration.Dispose(); }; cancellationTokenRegistration = cancellationToken.Register(cancellationCallback); } #endif return(result.Task); #endif }
/// <summary> /// Breaks down the buffer player into a state where it can no longer be used. /// </summary> public void StopSending() { waitHandle.Unregister(null); canPopulate.Close(); }
protected string SendReceive(string cmd, byte[] payload, string contentType) { AutoResetEvent done = new AutoResetEvent(false); string response = null; DateTime deadline = DateTime.Now.AddSeconds(Client.DefaultTimeout); string url = HttpClient.ServerUrl + "/" + cmd; while (deadline > DateTime.Now && null != url) { this.Log("SEND", url.ToString()); HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url); this._response = null; RegisteredWaitHandle timeoutHandler = ThreadPool.RegisterWaitForSingleObject(done, new WaitOrTimerCallback(this.OnTimeout), req, (int)((deadline - DateTime.Now).TotalMilliseconds), true); req.AllowAutoRedirect = false; req.Proxy = this.IP; req.Accept = HttpClient.ResponseContentType; req.UserAgent = Client.Version; req.KeepAlive = false; this._payload = payload; if (0 < this._payload.Length) { req.Expect = String.Empty; req.Method = "POST"; req.ContentType = contentType; req.ContentLength = this._payload.Length; this._ready.Reset(); try { req.BeginGetRequestStream(new AsyncCallback(this.OnReadyToSend), req); } catch (System.Exception e) { throw new IOException("API connection failed", e); } this._ready.WaitOne(); } else { req.Method = "GET"; } url = null; payload = new byte[0]; this._ready.Reset(); try { req.BeginGetResponse(new AsyncCallback(this.OnReadyToReceive), req); } catch (System.Exception e) { throw new IOException("API connection failed", e); } this._ready.WaitOne(); if (null != this._response) { if (HttpStatusCode.Forbidden == this._response.StatusCode) { throw new AccessDeniedException(); } else if (HttpStatusCode.BadRequest == this._response.StatusCode) { throw new InvalidCaptchaException(); } else if (HttpStatusCode.SeeOther == this._response.StatusCode) { try { url = (string)this._response.Headers["Location"]; } catch (System.Exception) { // } } else { using (StreamReader rd = new StreamReader(this._response.GetResponseStream(), Encoding.UTF8)) { response = rd.ReadToEnd(); } this.Log("RECV", response); } try { this._response.Close(); } catch (System.Exception) { // } } timeoutHandler.Unregister(done); } return(response); }
/* * 开始爆破++++++++++++++++++ */ public void Start() { try { if (Url.Count < 1) { MessageBox.Show("没有存活目标"); } else { ThreadPool.SetMinThreads(2, 1); //设置线程池在新请求预测中维护的空闲线程数 ThreadPool.SetMaxThreads(Thread_num, Thread_num); //设置线程池最大线程数,用来控制线程 listBox1.Items.Clear(); //结果输出框清空 suc_num = 0; listBox1.Items.Add("任务开始......"); RegisteredWaitHandle rhw = null;//为线监控程池线程结束做准备 DateTime start_time = DateTime.Now; if (comboBox2.SelectedIndex != 0) { Thread_num = Convert.ToInt32(comboBox2.SelectedItem); } for (int i = 0; i < Url.Count; i++) { string url = Url[i]; listBox2.Items.Add(url); Application.DoEvents();//重绘窗口,添加任务列表 long error_content; switch (OA_Selected) { case "tomcat": error_content = 123; break; default: error_content = GetErrorContent(url); break; } StreamReader sr_user = new StreamReader(User_path);//从该文件加载用户字典 while (!sr_user.EndOfStream) { string userName = sr_user.ReadLine(); //遍历用户名 StreamReader sr_pass = new StreamReader(Pass_path); //从该文件加载密码字典 while (!sr_pass.EndOfStream) { string userPass = sr_pass.ReadLine(); //遍历密码 ThreadPool.QueueUserWorkItem(brtue => Brute(url, userName, userPass, error_content)); //线程池,多线程开启任务 } sr_pass.Close(); } sr_user.Close(); } //监测线程池任务是否结束 rhw = ThreadPool.RegisterWaitForSingleObject(new AutoResetEvent(false), new WaitOrTimerCallback((obj, b) => { int workerThreads = 0; int maxWordThreads = 0; int compleThreads = 0; ThreadPool.GetAvailableThreads(out workerThreads, out compleThreads); ThreadPool.GetMaxThreads(out maxWordThreads, out compleThreads); //当可用的线数与池程池最大的线程相等时表示线程池中所有的线程已经完成 if (workerThreads == maxWordThreads) { rhw.Unregister(null); //此处是所有线程完成后的处理代码 DateTime end_time = DateTime.Now; var all_time = end_time - start_time; toolStripStatusLabel2.Text = "任务结束,总共成功破解 " + suc_num + " 个目标;共耗时" + all_time; MessageBox.Show("所有任务已经完成"); rhw = null; } }), null, 100, false); } } catch (Exception ex) { string message = "爆破时未知错误(Strat方法中)" + ex.ToString(); LogAdd ld = new LogAdd(Error_log); this.BeginInvoke(ld, new object[] { message }); } }
internal void DoClose( bool isShuttingDown, Exception reasonForClose) { if (_isClosed) { return; } lock (_syncObject) { if (_isClosed) { return; } _isClosed = true; _lastErrorReported = reasonForClose; if (!_isRequestPending) { // release threads blocked on the sending data to client if any _waitHandle.Set(); } } // only one thread will reach here // let everyone know that we are about to close try { RaiseClosingEvent(); foreach (var cmdTransportKvp in _activeCmdTransportManagers) { cmdTransportKvp.Value.Close(reasonForClose); } _activeCmdTransportManagers.Clear(); if (null != _registeredShutDownWaitHandle) { // This will not wait for the callback to complete. _registeredShutDownWaitHandle.Unregister(null); _registeredShutDownWaitHandle = null; } // Delete the context only if isShuttingDown != true. isShuttingDown will // be true only when the method is called from RegisterWaitForSingleObject // handler..in which case the context will be freed from the callback. if (null != _shutDownContext) { _shutDownContext = null; } // This might happen when client did not send a receive request // but the server is closing if (null != _requestDetails) { // Notify that no more data is being sent on this transport. WSManNativeApi.WSManPluginReceiveResult( _requestDetails.unmanagedHandle, (int)WSManNativeApi.WSManFlagReceive.WSMAN_FLAG_RECEIVE_RESULT_NO_MORE_DATA, WSManPluginConstants.SupportedOutputStream, IntPtr.Zero, WSManNativeApi.WSMAN_COMMAND_STATE_DONE, 0); WSManPluginInstance.ReportWSManOperationComplete(_requestDetails, reasonForClose); // We should not use request details again after reporting operation complete // so releasing the resource. Remember not to free this memory as this memory // is allocated and owned by WSMan. _requestDetails = null; } } finally { // dispose resources _waitHandle.Dispose(); } }
internal static void WaitForResponse(HttpRequestMessage request, ExpectedResponse arrival, TimeSpan requestTimeout, AmqpModelContainer model, bool closeModel, CancellationToken cancellationToken, TaskCompletionSource <HttpResponseMessage> taskSource, Action cleanup) { //Spawning a new task to wait on the MRESlim is slower than using ThreadPool.RegisterWaitForSingleObject // //TODO: Test task vs RegisterWaitForSingleObject modes in a super fast network environment with 40, 100, 200 all the way to 1000 threads to see what method has fastest throughput. #if WAIT_FOR_RESPONSE_IN_TASK_MODE //Wait for response arrival event on a new task Task.Factory.StartNew(() => { bool succeeded = arrival.ReceivedEvent.Wait( requestTimeout.TotalMilliseconds > Int32.MaxValue ? TimeSpan.FromMilliseconds(Int32.MaxValue) : requestTimeout /* Covers InfiniteTimeSpan */, cancellationToken); Thread.MemoryBarrier(); //Ensure non-cached versions of arrival are read //It failed either because it timed out or was cancelled //HttpClient treats both scenarios the same way. try { if (closeModel) { model.Close(); } SetResponseResult(request, !succeeded, arrival, taskSource); } catch { //TODO: Log this: // the code in the try block should be safe so this catch block should never be called, // hoewever, this delegate is called on a separate thread and should be protected. } finally { CleanupMessagingResources(correlationId, arrival); } }, cancellationToken); #else //Wait for response arrival event on the ThreadPool: var localVariableInitLock = new object(); lock (localVariableInitLock) { //TODO: Have cancellationToken signal WaitHandle so that threadpool stops waiting. RegisteredWaitHandle callbackHandle = null; callbackHandle = ThreadPool.RegisterWaitForSingleObject(arrival.ReceivedEvent.WaitHandle, (state, timedOut) => { //TODO: Investigate, this memorybarrier might be unnecessary since the thread is released from the threadpool //after deserializationException and responsePacket is set. Thread.MemoryBarrier(); //Ensure non-cached versions of arrival are read try { //TODO: Check Cancelation Token when it's implemented if (closeModel) { model.Close(); } SetResponseResult(request, timedOut, arrival, taskSource); lock (localVariableInitLock) { callbackHandle.Unregister(null); } } catch { //TODO: Log this: // the code in the try block should be safe so this catch block should never be called, // hoewever, this delegate is called on a separate thread and should be protected. } finally { cleanup(); } }, null, requestTimeout == System.Threading.Timeout.InfiniteTimeSpan ? System.Threading.Timeout.Infinite : (long)requestTimeout.TotalMilliseconds, true); } #endif }