asynchronousPOST在WP7和F#上失败
当我let! read = from.AsyncRead buf
let! read = from.AsyncRead buf
在F#中,它会阻塞,直到TCP套接字死亡才会返回。 为什么? 我该如何解决?
其代码:
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 ()
这是从这个代码被调用:
use fs = new FileStream(targPath, FileMode.CreateNew, FileAccess.ReadWrite) do! req.InputStream |>> fs
并使用Windows Phone 7.1模拟器中的代码通过HTTP进行请求:
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); // tried both 2 sw.Write(readBytes); //sw.Write(Convert.ToBase64String(readBytes)); sw.Flush(); sw.Close(); } req.BeginGetResponse(ResponseReady, req); }); } // WHY IS IT YOU ARE NOT CALLED??? void ResponseReady(IAsyncResult ar) { try { var request = (HttpWebRequest)ar.AsyncState; var response = request.EndGetResponse(ar); SmartDispatcher.BeginInvoke(() => { var rdr = new StreamReader(response.GetResponseStream()); var msg = rdr.ReadToEnd(); var imageLocation = response.Headers["Location"]; Debug.WriteLine(msg); Debug.WriteLine(imageLocation); }); } catch (WebException ex) { Debug.WriteLine(ex.ToString()); } catch (Exception ex) { Debug.WriteLine(ex.ToString()); } }
不成功。 ResponseReady
callback永远不会到达。
同时,这个代码工作出色:
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
我无法让Fiddler2与WP7一起工作。
编辑:欢迎来到牦牛。 我自己已经进入了更加绿色的牧场;)
你应该把这些字节放入发送和使用BufferStream INput输出之前