Khi tôi làm let! read = from.AsyncRead buf
trong F #, nó chặn và không trở lại cho đến khi cổng TCP bị chết. Tại sao? Và làm thế nào để sửa nó?Không đồng bộ POST trên WP7 và F #
mã của nó:
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()
Nó đang được gọi là từ mã này:
use fs = new FileStream(targPath, FileMode.CreateNew, FileAccess.ReadWrite)
do! req.InputStream |>> fs
và yêu cầu qua HTTP với mã này từ Windows Phone 7.1 giả lập:
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());
}
}
không thành công. Cuộc gọi lại ResponseReady
không bao giờ được tiếp cận.
Trong khi đó, mã này làm việc tuyệt vời:
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
tôi không thể có được Fiddler2 làm việc với WP7.
EDIT: Chào mừng bạn đến với một yak. Tôi đã chuyển sang đồng cỏ xanh hơn bản thân mình;)
Nếu 'khối from.AsyncRead' đó có nghĩa là máy chủ từ xa không gửi bất kỳ byte. – qehgt
Tôi đã nhận được từ các vấn đề mà dòng không đóng đúng cách, nhưng tôi vẫn chỉ nhận được các tập tin có kích thước 40 byte lớn ở phía bên nhận và trên WP rất nhiều hoạt động đang chặn ném NotSupportedException thay vì không có sẵn, do đó, nó thực sự đau đớn để gỡ lỗi. Tôi sẽ đăng một giải pháp hoàn chỉnh khi tôi đến đó. – Henrik
Tôi chưa quên câu hỏi này; chỉ cần làm rất nhiều việc ngay bây giờ, sẽ đăng sửa ngay. – Henrik