#pragma warning restore 1998 #region UsingAsyncBuildingBlock public Task Using(StringBuilder builder) { return(TaskBlocks.Using( () => AcquireResourceAsync(builder), task => task.Result.WriteAsync(SampleText))); }
protected internal override Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { if (disposed != 0) { throw new ObjectDisposedException(GetType().ToString()); } Interlocked.Exchange(ref sentRequest, 1); wrequest = CreateWebRequest(request); Task intermediate; if (request.Content != null) { AddContentHeaders(wrequest, request.Content.Headers); intermediate = wrequest.GetRequestStreamAsync() .Then(streamTask => request.Content.CopyToAsync(streamTask.Result).Finally(_ => streamTask.Result.Dispose())); } else if (HttpMethod.Post.Equals(request.Method) || HttpMethod.Put.Equals(request.Method) || HttpMethod.Delete.Equals(request.Method)) { // Explicitly set this to make sure we're sending a "Content-Length: 0" header. // This fixes the issue that's been reported on the forums: // http://forums.xamarin.com/discussion/17770/length-required-error-in-http-post-since-latest-release wrequest.ContentLength = 0; intermediate = Task.FromResult(default(VoidResult)); } else { intermediate = Task.FromResult(default(VoidResult)); } HttpWebResponse wresponse = null; Func <Task <IDisposable> > resource = () => Task.FromResult <IDisposable>(cancellationToken.Register(l => ((HttpWebRequest)l).Abort(), wrequest)); Func <Task <IDisposable>, Task> body = _ => { return(wrequest.GetResponseAsync().Select(task => wresponse = (HttpWebResponse)task.Result) .Catch <WebException>( (task, we) => { if (we.Status == WebExceptionStatus.ProtocolError) { // HttpClient shouldn't throw exceptions for these errors wresponse = (HttpWebResponse)we.Response; } else if (we.Status != WebExceptionStatus.RequestCanceled) { // propagate the antecedent return task; } return Task.FromResult(default(VoidResult)); }) .Then( task => { if (cancellationToken.IsCancellationRequested) { return Task.FromCanceled <HttpResponseMessage>(cancellationToken); } else { return Task.FromResult(default(VoidResult)); } })); }; return(intermediate .Then(_ => TaskBlocks.Using(resource, body)) .Select(_ => CreateResponseMessage(wresponse, request, cancellationToken))); }
protected internal override Task SerializeToStreamAsync(Stream stream, TransportContext context) { // RFC 2046 // // The Content-Type field for multipart entities requires one parameter, // "boundary". The boundary delimiter line is then defined as a line // consisting entirely of two hyphen characters ("-", decimal value 45) // followed by the boundary parameter value from the Content-Type header // field, optional linear whitespace, and a terminating CRLF. // byte[] buffer; var sb = new StringBuilder(); sb.Append('-').Append('-'); sb.Append(boundary); sb.Append('\r').Append('\n'); int i = 0; Func <bool> condition = () => i < nested_content.Count; Func <Task> body = () => { var c = nested_content[i]; foreach (var h in c.Headers) { sb.Append(h.Key); sb.Append(':').Append(' '); foreach (var v in h.Value) { sb.Append(v); } sb.Append('\r').Append('\n'); } sb.Append('\r').Append('\n'); buffer = Encoding.ASCII.GetBytes(sb.ToString()); sb.Length = 0; return(stream.WriteAsync(buffer, 0, buffer.Length) .Then(_ => c.SerializeToStreamAsync(stream, context)) .Select( _ => { if (i != nested_content.Count - 1) { sb.Append('\r').Append('\n'); sb.Append('-').Append('-'); sb.Append(boundary); sb.Append('\r').Append('\n'); } i++; })); }; Func <Task, Task> continuationFunction = task => { sb.Append('\r').Append('\n'); sb.Append('-').Append('-'); sb.Append(boundary); sb.Append('-').Append('-'); sb.Append('\r').Append('\n'); buffer = Encoding.ASCII.GetBytes(sb.ToString()); return(stream.WriteAsync(buffer, 0, buffer.Length)); }; return(TaskBlocks.While(condition, body) .Then(continuationFunction)); }
#pragma warning restore 1998 #region UsingWithResultAsyncBuildingBlock public Task <string> UsingWithResult() { return(TaskBlocks.Using( () => AcquireResourceAsync(), task => task.Result.ReadToEndAsync())); }