0

我对 Windows Phone 7 WebRequests 有一点问题。在我的程序中,很少有“网络进程”——每个进程都必须向服务器发送一条或多条 REST-s 消息。来自对该消息的响应的信息将用于下一个 REST,因此所有 WebRequest 必须以正确的顺序发送。因此,为了轻松同步所有消息,我创建了这样的方法:

//There was some try-catch blocks,  I cut them because they are not important 
//for the problem
public string SendString(string URL, string message)
        {
            WebRequest wr = HttpWebRequest.CreateHttp(URL);
            wr.Method = "POST";
            var req = Observable.FromAsyncPattern<Stream>(wr.BeginGetRequestStream, wr.EndGetRequestStream);
            var resp = Observable.FromAsyncPattern<WebResponse>(wr.BeginGetResponse, wr.EndGetResponse);
            WebResponse WR = req().SelectMany(reqStream =>
                {
                    byte[] stream = UTF8Encoding.UTF8.GetBytes(message);
                    reqStream.Write(stream, 0, stream.Length);
                    reqStream.Close();
                    return resp();
                })
                .First();
            Stream respStream = WR.GetResponseStream();
            StreamReader readStream = new StreamReader(respStream, UTF8Encoding.UTF8);
            String response = readStream.ReadToEnd();
            _acctualResponse = response;

            return _acctualResponse;
        }

当然,“web 进程”是异步运行的:

Observable.Start(() => _registration.Execute(String.Empty)).Subscribe();

问题是,当 UI 线程忙时,直到 UI 线程空闲时才会响应。我不知道为什么。也许有人会帮助我。

编辑

我制作了一些伪图来可视化我的应用程序的结构。每个过程都必须是异步的,而且每个动作都必须等待前一个动作的结果。

申请流程

编辑 2

部分代码Action,在所有情况下都非常简单,如下所示:

public override JsonMap.Response Perform(string token)
        {
            JsonMap.authenticationRequest dataToSend = new JsonMap.authenticationRequest
            {
                tid = token,
                platform = "wp7",
                version = "1.0.0",
                userid = ApplicationData.Instance.UserID
            };
            string jsonDataToSend = JsonConvert.SerializeObject(dataToSend,Formatting.Indented,new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
            string jsonResponse = _webClient.SendString(_serviceURL, jsonDataToSend);
            Response response = JsonConvert.DeserializeObject<Response>(jsonResponse);
            return response;

        }
4

1 回答 1

1

我怀疑你的问题是你正在打电话First(),这是一个阻塞电话。

每当你打电话First()时,你可能做错了什么。

您可能已经走上了这条“黑暗之路”,因为您的函数签名也是阻塞签名。您需要将其更改为:

public IObservable<string> SendString(string URL, string message)

现在您可以像这样编写函数:

public IObservable<string> SendString(string URL, string message)
{
    WebRequest hwr = HttpWebRequest.CreateHttp(URL);
    hwr.Method = "POST";

    Func<IObservable<Stream>> getRequest = 
        Observable
            .FromAsyncPattern<Stream>(
                hwr.BeginGetRequestStream,
                hwr.EndGetRequestStream);

    Func<Stream, IObservable<WebResponse>> getResponse = ...

    Func<WebResponse, string> getResult = ...

    return
        from rq in getRequest()
        from rp in getResponse(rq)
        select getResult(rp);
}

请注意,最终查询确实很整洁。

getResponse函数如下所示:

    Func<Stream, IObservable<WebResponse>> getResponse =
        st =>
        {
            var resp =
                Observable
                    .FromAsyncPattern<WebResponse>(
                        hwr.BeginGetResponse,
                        hwr.EndGetResponse);
            var bytes = UTF8Encoding.UTF8.GetBytes(message);
            st.Write(bytes, 0, bytes.Length);
            st.Close();
            return resp();          
        };

getResult看起来像这样:

    Func<WebResponse, string> getResult =
        wr =>
        {
            using (var st = wr.GetResponseStream())
            {
                using (var sr = new StreamReader(st, UTF8Encoding.UTF8))
                {
                    return sr.ReadToEnd();
                }
            }
        };

最后,您需要订阅结果 observable 以获得结果。您可能需要调用ObserveOn以使调用返回到 UI 线程。

让我知道这是否有帮助。

于 2012-05-19T05:15:33.680 回答