0

Windows Phone 7 の WebRequests に少し問題があります。私のプログラムにはいくつかの「Web プロセス」があります。それぞれが 1 つ以上の REST メッセージをサーバーに送信する必要があります。このメッセージに対する応答の情報は、次の 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();
                }
            }
        };

最後に、結果を取得するには、結果のオブザーバブルをサブスクライブする必要があります。ObserveOnUI スレッドに戻るには、呼び出しを取得する必要がある場合があります。

これが役立つかどうか教えてください。

于 2012-05-19T05:15:33.680 に答える