1

これが私のコードです:

namespace RequestApi
{
    public partial class MainPage : PhoneApplicationPage
    {
        private BackgroundWorker bw;
        private string ans;
        private JObject ansJson;
        private static ManualResetEvent allDone = new ManualResetEvent(false);
        // Constructor
        public MainPage()
        {
            InitializeComponent();

        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            string url = "http://192.168.0.43:8182/Account/SignIn";
            CreateRequest(url);

            userId.Text = ansJson.Value<int>("user_id").ToString();

        }


        private void CreateRequest(string url)
        {
            Debug.WriteLine("CreateRequest");
            HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url);
            req.ContentType = "application/json";
            req.Method = "POST";
            req.BeginGetRequestStream(new AsyncCallback(RequestCallback), req);
            allDone.WaitOne();
        }

        private  void RequestCallback(IAsyncResult aresult)
        {
            Debug.WriteLine("RequestCallback");
            HttpWebRequest req = (HttpWebRequest)aresult.AsyncState;
            Stream postStream = req.EndGetRequestStream(aresult);

            string obj = "{ 'username': 'test_2@aragast.com', 'password': 'a123456' }";
            JObject json = JObject.Parse(obj);
            string s = JsonConvert.SerializeObject(json);
            byte[] postdata = System.Text.Encoding.Unicode.GetBytes(s);

            postStream.Write(postdata, 0, postdata.Length);
            postStream.Close();

            req.BeginGetResponse(new AsyncCallback(ResponseCallback), req);


        }

        private  void ResponseCallback(IAsyncResult aresult)
        {
            Debug.WriteLine("ResponseCallback");
            HttpWebRequest req = (HttpWebRequest)aresult.AsyncState;
            HttpWebResponse resp = (HttpWebResponse)req.EndGetResponse(aresult);
            StreamReader reader = new StreamReader(resp.GetResponseStream());
            string response = reader.ReadToEnd();
            Debug.WriteLine(response);
            JObject responseJson = JObject.Parse(response);
            ansJson = responseJson;
            Debug.WriteLine("ansJson from responseCallback {0}", ansJson);
            reader.Close();
            resp.Close();
            allDone.Set();

        }
    }
}

アプリケーションをデバッグすると、CreateRequest に入り、RequestCallback に入りますが、停止して ResponseCallback に入ることはありません。私が間違ったとき、なぜそれが ResponseCallback に入らないのですか?

4

2 に答える 2

2

あなたManualResetEventは引数としてで作成されてtrueいるので、それはすでにで始まるように合図されています。つまり、allDone.Wait()呼び出しはすぐに続行されます...CreateRequest終了し、すぐに変数を使用しようとします。asnJsonこれは、あなたが言ったようにですnull。それはアプリケーションを殺すだろう、と私は思う-それであなたは応答を得る機会を決して得ることができない。

さて、これに対する解決策はコンストラクターを変更しないManualResetEventことです-とにかくUIスレッドでそのように待つべきではありません!これをブロックし、Windows Phone 7のすべてのポイントを削除して、最初からすべてを非同期にします。

代わりに、コールバックはディスパッチャーを使用して、終了時にUIスレッドにコールバックする必要があります。リクエストで問題が発生した場合に備えて、堅牢なエラー処理も必要であることに注意してください。

于 2011-10-06T16:48:41.683 に答える
1

質問への回答とは正確には関係ありませんが、回答ブロックは、これから行う推奨事項に適合する唯一の場所のようです...次のようなusingブロックを使用して、ストリームの周りに適切なリソース保護を行う必要があります。

元のコード:

        Stream postStream = req.EndGetRequestStream(aresult);

        string obj = "{ 'username': 'test_2@aragast.com', 'password': 'a123456' }";
        JObject json = JObject.Parse(obj);
        string s = JsonConvert.SerializeObject(json);
        byte[] postdata = System.Text.Encoding.Unicode.GetBytes(s);

        postStream.Write(postdata, 0, postdata.Length);
        postStream.Close();

新しいコード (エンコーディングがリクエストに対して正しいことも確認してください: Web サービスは本当に UTF-16 を予期していますか? Web サーバーが UTF-8 (Encoding.UTF8) を使用するのがより一般的です):

        using (Stream postStream = req.EndGetRequestStream(aresult))
        {
            string obj = "{ 'username': 'test_2@aragast.com', 'password': 'a123456' }";
            JObject json = JObject.Parse(obj);
            string s = JsonConvert.SerializeObject(json);
            byte[] postdata = System.Text.Encoding.Unicode.GetBytes(s);

            postStream.Write(postdata, 0, postdata.Length);
        }

元のコード:

        HttpWebResponse resp = (HttpWebResponse)req.EndGetResponse(aresult);
        StreamReader reader = new StreamReader(resp.GetResponseStream());
        string response = reader.ReadToEnd();
        Debug.WriteLine(response);
        JObject responseJson = JObject.Parse(response);
        ansJson = responseJson;
        Debug.WriteLine("ansJson from responseCallback {0}", ansJson);
        reader.Close();
        resp.Close();

新しいコード:

        using (HttpWebResponse resp = (HttpWebResponse)req.EndGetResponse(aresult))
        using (StreamReader reader = new StreamReader(resp.GetResponseStream()))
        {
            string response = reader.ReadToEnd();
            Debug.WriteLine(response);
            JObject responseJson = JObject.Parse(response);
            ansJson = responseJson;
            Debug.WriteLine("ansJson from responseCallback {0}", ansJson);
        }

reqまた、何かが例外的な条件を処理できるように、resp操作をブロックで囲むことをお勧めします。try..catchそうしないと、AppDomain の例外ハンドラーにバブルアップします (UnhandledException イベントによってフックされることもあります)。

于 2011-10-06T17:52:07.933 に答える