public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback callback, object state) { string name = context.Request.QueryString["name"]; if (string.IsNullOrEmpty(name)) { return(Futures.ImmediateFuture( new HttpQueryResponse { Name = string.Empty, Response = string.Empty, StatusCode = HttpStatusCode.NotFound })); } IDictionary <string, string> parameters = GetParameters(context); var app = context .Application[Strings.kApplicationKey] as HttpQueryApplication; var async_state = new AsyncState(context.GetHashCode(), context); IFuture <HttpQueryResponse> result = app.ProcessQuery(name, parameters, callback, async_state); // Waits the processing to finish. NOTE that we cannot finish the // request synchrnously, because that is no way to tell ASP.NET // that the request has been completed. If we do this a null reference // exception will be raised when OnAsyncHandlerCompletion runs, because // the HttpContext associated with the request is already released. HttpQueryResponse response; if (result.TryGet(0, TimeUnit.Seconds, out response)) { callback(result); return(Futures.ImmediateFuture(0)); } pending_request_[async_state.ID] = name; ThreadPool.RegisterWaitForSingleObject(result.AsyncWaitHandle, (o, @out) => Timeout(@out, callback, result), null, app.Settings.ResponseTimeout, true); return(result); }
/// <summary> /// Invokes <see cref="IFuture{T}.TryGet"/> uninterruptibly. /// </summary> /// <param name="future">The future whose value should be get /// uninterruptibly.</param> /// <param name="timeout"> /// The maximum time to wait. /// </param> /// <param name="unit"> /// The time unit of the timeout argument. /// </param> /// <param name="result"> /// The result of the computation, or the default /// value for <typeparamref name="T"/> if the wait timed out. /// </param> /// <returns> /// The result of the future computation. /// </returns> /// <exception cref="ExecutionException"> /// if the computation threw an exception. /// </exception> /// <exception cref="OperationCanceledException"> /// If the current thread was interrupted while waiting. /// </exception> /// <seealso cref="IFuture{T}"/> /// <seealso cref="IFuture{T}.TryGet(long, TimeUnit, out T)"/> public static bool GetUninterruptibly <T>(IFuture <T> future, long timeout, TimeUnit unit, out T result) { bool interrupted = false; try { while (true) { try { return(future.TryGet(timeout, unit, out result)); } catch (ThreadInterruptedException) { interrupted = true; } } } finally { if (interrupted) { Thread.CurrentThread.Interrupt(); } } }