/// <summary> /// Подождать завершение задачи /// </summary> public void Wait() { if (_isCompleted) { if (_isCancelled) { throw new OperationInterruptedException(); } if (_exception != null) { _exception.Throw(); } return; } lock (_syncObject) { while (!_isCompleted) { Monitor.Wait(_syncObject); } } if (_isCancelled) { throw new OperationInterruptedException(); } if (_exception != null) { _exception.Throw(); } }
/// <summary> /// Issues an HTTP request for the current request context. /// </summary> /// <typeparam name="T">The response type for the current request.</typeparam> /// <param name="executionContext">The execution context, it contains the /// request and response context.</param> /// <returns>A task that represents the asynchronous operation.</returns> public override async System.Threading.Tasks.Task <T> InvokeAsync <T>(IExecutionContext executionContext) { IHttpRequest <TRequestContent> httpRequest = null; try { SetMetrics(executionContext.RequestContext); IRequest wrappedRequest = executionContext.RequestContext.Request; httpRequest = CreateWebRequest(executionContext.RequestContext); httpRequest.SetRequestHeaders(wrappedRequest.Headers); using (executionContext.RequestContext.Metrics.StartEvent(Metric.HttpRequestTime)) { // Send request body if present. if (wrappedRequest.HasRequestBody()) { System.Runtime.ExceptionServices.ExceptionDispatchInfo edi = null; try { // In .NET Framework, there needs to be a cancellation token in this method since GetRequestStreamAsync // does not accept a cancellation token. A workaround is used. This isn't necessary in .NET Standard // where the stream is a property of the request. #if BCL45 var requestContent = await httpRequest.GetRequestContentAsync(executionContext.RequestContext.CancellationToken).ConfigureAwait(false); await WriteContentToRequestBodyAsync(requestContent, httpRequest, executionContext.RequestContext).ConfigureAwait(false); #else var requestContent = await httpRequest.GetRequestContentAsync().ConfigureAwait(false); WriteContentToRequestBody(requestContent, httpRequest, executionContext.RequestContext); #endif } catch (Exception e) { edi = System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(e); } if (edi != null) { await CompleteFailedRequest(executionContext, httpRequest).ConfigureAwait(false); edi.Throw(); } } var response = await httpRequest.GetResponseAsync(executionContext.RequestContext.CancellationToken). ConfigureAwait(false); executionContext.ResponseContext.HttpResponse = response; } // The response is not unmarshalled yet. return(null); } finally { if (httpRequest != null) { httpRequest.Dispose(); } } }
/// <summary> /// Adds an item to the cache. /// </summary> /// <param name="store">The store storing the cache data.</param> /// <param name="name">The name of the cache item.</param> /// <param name="content">The cached data.</param> /// <returns>A <see cref="Task"/> representing the asynchronous caching operation.</returns> public async Task Add(String name, Stream content, String store) { Contract.Requires <ArgumentNullException>(name != null); Contract.Requires <ArgumentNullException>(content != null); Contract.Requires <ArgumentNullException>(store != null); System.Runtime.ExceptionServices.ExceptionDispatchInfo exceptionInfo = null; try { long length = content.Length; await this.WriteToFileAsync(content, await this.OpenStore(store), name); cacheEventSource.ItemStored(name, store, length); } catch (IOException ex) { exceptionInfo = System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(ex); } if (exceptionInfo != null) // Little hacky (but required!) as we can't use async / await inside a catch-block { int hresult = exceptionInfo.SourceException.HResult & 0xFFFF; if (hresult == 0x70 || hresult == 0x27) // HResults for disk full. { await this.Invalidate(); } else { exceptionInfo.Throw(); } } }
public void SetException(System.Runtime.ExceptionServices.ExceptionDispatchInfo edi, TaskScheduler sheduler = null) { lock (_lock) { _completionAction = () => { edi.Throw(); }; Complete(sheduler); } }
/// <summary> /// Issues an HTTP request for the current request context. /// </summary> /// <typeparam name="T">The response type for the current request.</typeparam> /// <param name="executionContext">The execution context, it contains the /// request and response context.</param> /// <returns>A task that represents the asynchronous operation.</returns> public override async System.Threading.Tasks.Task <T> InvokeAsync <T>(IExecutionContext executionContext) { IHttpRequest <TRequestContent> httpRequest = null; try { SetMetrics(executionContext.RequestContext); IRequest wrappedRequest = executionContext.RequestContext.Request; httpRequest = CreateWebRequest(executionContext.RequestContext); httpRequest.SetRequestHeaders(wrappedRequest.Headers); using (executionContext.RequestContext.Metrics.StartEvent(Metric.HttpRequestTime)) { // Send request body if present. if (wrappedRequest.HasRequestBody()) { System.Runtime.ExceptionServices.ExceptionDispatchInfo edi = null; try { var requestContent = await httpRequest.GetRequestContentAsync().ConfigureAwait(false); WriteContentToRequestBody(requestContent, httpRequest, executionContext.RequestContext); } catch (Exception e) { edi = System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(e); } if (edi != null) { await CompleteFailedRequest(executionContext, httpRequest).ConfigureAwait(false); edi.Throw(); } } var response = await httpRequest.GetResponseAsync(executionContext.RequestContext.CancellationToken). ConfigureAwait(false); executionContext.ResponseContext.HttpResponse = response; } // The response is not unmarshalled yet. return(null); } finally { if (httpRequest != null) { httpRequest.Dispose(); } } }
/// <summary> /// Invokes the inner handler and performs a retry, if required as per the /// retry policy. /// </summary> /// <typeparam name="T">The response type for the current request.</typeparam> /// <param name="executionContext">The execution context, it contains the /// request and response context.</param> /// <returns>A task that represents the asynchronous operation.</returns> public override async System.Threading.Tasks.Task <T> InvokeAsync <T>(IExecutionContext executionContext) { var requestContext = executionContext.RequestContext; var responseContext = executionContext.ResponseContext; bool shouldRetry = false; await this.RetryPolicy.ObtainSendTokenAsync(executionContext, null).ConfigureAwait(false); do { System.Runtime.ExceptionServices.ExceptionDispatchInfo capturedException = null; try { SetRetryHeaders(requestContext); T result = await base.InvokeAsync <T>(executionContext).ConfigureAwait(false); this.RetryPolicy.NotifySuccess(executionContext); return(result); } catch (Exception e) { capturedException = System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(e); } if (capturedException != null) { shouldRetry = await this.RetryPolicy.RetryAsync(executionContext, capturedException.SourceException).ConfigureAwait(false); if (!shouldRetry) { LogForError(requestContext, capturedException.SourceException); capturedException.Throw(); } else { requestContext.Retries++; requestContext.Metrics.SetCounter(Metric.AttemptCount, requestContext.Retries); LogForRetry(requestContext, capturedException.SourceException); } await this.RetryPolicy.ObtainSendTokenAsync(executionContext, capturedException.SourceException).ConfigureAwait(false); } PrepareForRetry(requestContext); using (requestContext.Metrics.StartEvent(Metric.RetryPauseTime)) await RetryPolicy.WaitBeforeRetryAsync(executionContext).ConfigureAwait(false); } while (shouldRetry); throw new AmazonClientException("Neither a response was returned nor an exception was thrown in the Runtime RetryHandler."); }
public static void ReadLineAndSendLoop(IApplicationClient InnerClient, Action <SecureContext> SetSecureContext, Boolean UseOld, Object Lockee) { var NeedToExit = false; AutoResetEvent NeedToCheck = new AutoResetEvent(false); System.Runtime.ExceptionServices.ExceptionDispatchInfo edi = null; InnerClient.ServerShutdown += e => { Console.WriteLine("服务器已关闭。"); lock (Lockee) { NeedToExit = true; } NeedToCheck.Set(); }; InnerClient.Error += e => { var m = e.Message; Console.WriteLine(m); }; InnerClient.MessageReceived += e => Console.WriteLine(e.Content); InnerClient.MessageReceivedAt2 += e => { if (e.Title != "") { Console.WriteLine(e.Title); } foreach (var Line in e.Lines) { Console.WriteLine(Line); } }; ((Func <Task>)(async() => { var r = await InnerClient.CheckSchemaVersion(new CheckSchemaVersionRequest { Hash = UseOld ? "D7FFBD0D2E5D7274" : InnerClient.Hash.ToString("X16") }); if (r.OnHead) { } else if (r.OnSupported) { Console.WriteLine("客户端不是最新版本,但服务器可以支持。"); } else if (r.OnNotSupported) { Console.WriteLine("客户端版本不受支持。"); lock (Lockee) { NeedToExit = true; } NeedToCheck.Set(); } else { throw new InvalidOperationException(); } }))(); while (true) { String Line = null; ThreadPool.QueueUserWorkItem(o => { var l = Console.ReadLine(); lock (Lockee) { Line = l; } NeedToCheck.Set(); }); while (true) { if (NeedToExit) { return; } String l; lock (Lockee) { l = Line; } if (l != null) { break; } NeedToCheck.WaitOne(); if (edi != null) { edi.Throw(); } } lock (Lockee) { HandleLine(InnerClient, SetSecureContext, UseOld, Line).ContinueWith(tt => { if (tt.IsFaulted) { edi = System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(tt.Exception.InnerException ?? tt.Exception); NeedToCheck.Set(); return; } if (!tt.Result) { lock (Lockee) { NeedToExit = true; } NeedToCheck.Set(); } }); } } }