पर विफल रहता है जब मैं 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 के साथ काम नहीं कर रहा हो सकता है।
संपादित करें: एक याक में आपका स्वागत है। मैं हरित चराई पर अपने आप को स्थानांतरित किया है;)
भेजने और का उपयोग कर 'अगर from.AsyncRead' ब्लॉक इसका मतलब है कि दूरस्थ सर्वर किसी भी बाइट नहीं भेजा जाता है से पहले में बाइट्स रखना चाहिए। – qehgt
मुझे समस्या से दूर हो गया है कि स्ट्रीम ठीक से बंद नहीं होती है, लेकिन मुझे अभी भी प्राप्त करने वाले पक्ष पर 40 बाइट्स बड़े आकार में फाइलें मिल रही हैं और डब्ल्यूपी पर बहुत सारे ऑपरेशन जो थ्रो अवरुद्ध कर रहे हैं, न कि समर्थित नहीं होने के बजाय उपलब्ध है, तो यह डीबग करने के लिए वास्तव में दर्दनाक है। जब मैं उस पर पहुंचता हूं तो मैं एक पूरा समाधान पोस्ट करने जा रहा हूं। – Henrik
मैं इस सवाल को नहीं भूल गया; अभी करने के लिए बहुत कुछ, जल्द ही ठीक हो जाएगा। – Henrik