2012-05-16 10 views
84

'da başarısız oluyor. F # içinde let! read = from.AsyncRead buf yaptığımda, engellenir ve TCP soketi bitene kadar geri dönmez. Niye ya? Ve bunu nasıl düzeltirim?Async POST, WP7 ve F #

Onun kodu: Bu kod çağrılan ediliyor

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 

ve Windows Phone 7.1 emülatörü bu kodla HTTP üzerinden talep etti:

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()); 
    } 
} 

Başarısız oldu. ResponseReady geri arama hiçbir zaman ulaşılamaz.

arada, bu kod mükemmel çalışır:

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 

Ben WP7 ile çalışan Fiddler2 alamadım.

DÜZENLEME: Yak'a hoş geldiniz.

+9

gönderme ve kullanmadan önce içine bayt koymalıyız); ben daha iyi koşullar üzerine kendimi taşıdık. – qehgt

+0

Sorundan uzaklaştım, akış düzgün bir şekilde kapanmıyor, ancak hala sadece alıcı tarafında 40 bayt büyüklüğünde dosyalar alıyorum ve WP'ye çok fazla işlem yapmamak yerine NotSupportedException komutunu engelliyorsunuz. kullanılabilir, bu yüzden hata ayıklama gerçekten acı verici. Geldiğimde tam bir çözüm göndereceğim. – Henrik

+0

Bu soruyu unutmadım; Hemen şimdi yapacak çok şey, kısa sürede düzeltme gönderecek. – Henrik

cevap

1

YOu uzak sunucu herhangi bir bayt göndermek anlamına gelir from.AsyncRead` blokları `Eğer BufferStream giriş çıkış