When I do let! read = from.AsyncRead buf let! read = from.AsyncRead buf in F #, it blocks and does not return until the TCP socket is dead. What for? And how to fix it?
His code is:
module StreamUtil open System.IO /// copy from 'from' stream to 'toStream' let (|>>) (from : Stream) (toStream : Stream) = let buf = Array.zeroCreate<byte> 1024 let rec doBlock () = async { let! read = from.AsyncRead buf if read <= 0 then toStream.Flush() return () else do! toStream.AsyncWrite(buf, 0, read) return! doBlock () } doBlock ()
It is called from this code:
use fs = new FileStream(targPath, FileMode.CreateNew, FileAccess.ReadWrite) do! req.InputStream |>> fs
and requested via HTTP using this code from the Windows Phone 7.1 emulator:
public void Send() { var b = new UriBuilder(_imageService.BaseUrl) {Path = "/images"}; var req = WebRequest.CreateHttp(b.Uri); req.ContentType = "image/jpeg"; req.Method = "POST"; var imgLen = SelectedImage.ImageStream.Length; req.Headers[HttpRequestHeader.ContentLength] = imgLen.ToString(CultureInfo.InvariantCulture); req.Accept = "application/json"; req.BeginGetRequestStream(RequestReady, new ReqState(req, imgLen)); } void RequestReady(IAsyncResult ar) { var state = (ReqState)ar.AsyncState; var req = state.Request; var reqStream = req.EndGetRequestStream(ar); SmartDispatcher.BeginInvoke(() => { using (var sw = new StreamWriter(reqStream)) using (var br = new BinaryReader(SelectedVoucher.ImageStream)) { var readBytes = br.ReadBytes(state.ImgLen);
Unsuccessfully. The ResponseReady callback is never reached.
Meanwhile, this code works fine:
open System open System.Net.Http // WebAPI nuget let sync aw = Async.RunSynchronously aw let postC<'a> (c : HttpClient) (r : Uri) (cont : HttpContent) = let response = sync <| Async.AwaitTask( c.PostAsync(r, cont) ) let struc:'a = sync <| deserialize<'a> response response, struc let withContent<'a> (fVerb : (HttpClient -> Uri -> HttpContent -> _ * 'a))= let c = new HttpClient() fVerb c [<Test>] let ``POST /images 201 + Location header`` () = let post = withContent<MyImage> postC let bytes = IO.File.ReadAllBytes("sample.jpg") let hash = SHA1.Create().ComputeHash(bytes) |> Convert.ToBase64String let pic = new ByteArrayContent(bytes) pic.Headers.Add("Content-Type", "image/jpeg") pic.Headers.Add("X-SHA1-Hash", hash) let resp, ri = (resource "/images", pic) ||> post resp.StatusCode =? Code.Created ri.sha1 =? hash mustHaveHeaders resp
I could not get Fiddler2 to work with WP7.
EDIT: Welcome to yak. I myself moved to greener pastures;)
rest asynchronous windows-phone f #
Henrik May 16 '12 at 9:17 a.m. 2012-05-16 09:17
source share