2012-05-16 13 views
84

पर विफल रहता है जब मैं F12 में let! read = from.AsyncRead buf करता हूं, तो यह ब्लॉक करता है और टीसीपी सॉकेट मरने तक वापस नहीं आता है। क्यूं कर? और इसे किस प्रकार से ठीक किया जाए।Async POST WP7 और F #

इसका कोड:

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 

और विंडोज फोन 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 कॉलबैक कभी नहीं पहुंचा है।

इस बीच, इस कोड को उत्कृष्ट काम करता है:

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 के साथ काम नहीं कर रहा हो सकता है।

संपादित करें: एक याक में आपका स्वागत है। मैं हरित चराई पर अपने आप को स्थानांतरित किया है;)

+9

भेजने और का उपयोग कर 'अगर from.AsyncRead' ब्लॉक इसका मतलब है कि दूरस्थ सर्वर किसी भी बाइट नहीं भेजा जाता है से पहले में बाइट्स रखना चाहिए। – qehgt

+0

मुझे समस्या से दूर हो गया है कि स्ट्रीम ठीक से बंद नहीं होती है, लेकिन मुझे अभी भी प्राप्त करने वाले पक्ष पर 40 बाइट्स बड़े आकार में फाइलें मिल रही हैं और डब्ल्यूपी पर बहुत सारे ऑपरेशन जो थ्रो अवरुद्ध कर रहे हैं, न कि समर्थित नहीं होने के बजाय उपलब्ध है, तो यह डीबग करने के लिए वास्तव में दर्दनाक है। जब मैं उस पर पहुंचता हूं तो मैं एक पूरा समाधान पोस्ट करने जा रहा हूं। – Henrik

+0

मैं इस सवाल को नहीं भूल गया; अभी करने के लिए बहुत कुछ, जल्द ही ठीक हो जाएगा। – Henrik

उत्तर

1

आप BufferStream इनपुट आउटपुट