为什么没有调用BeginGetResponse回调?

本文关键字:回调 BeginGetResponse 调用 为什么 | 更新日期: 2023-09-27 18:10:48

我的代码:

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("answersJson from responseCallback {0}", ansJson);
            reader.Close();
            resp.Close();
            allDone.Set();
        }
    }
}

当我调试应用程序时,它进入CreateRequest然后进入RequestCallback,但随后它停止并且永远不会进入ResponseCallback,而是尝试userId。文本来分配asnJson值,该值为空,因为它没有输入ResponseCallback。当我做错了,为什么它从来没有进入ResponseCallback?

为什么没有调用BeginGetResponse回调?

您的ManualResetEvent是用true作为参数创建的,因此它已经被标记为开始。这意味着allDone.Wait()呼叫将立即继续…因此CreateRequest将完成,并且您将立即尝试使用asnJson变量,如您所说的是null。我怀疑这将终止应用程序,因此您永远没有机会获得响应。

现在,解决这个问题的方法是而不是来改变ManualResetEvent的构造函数——你不应该在UI线程中等待这样的时间!你会阻止它,你就失去了Windows Phone 7让一切从一开始就异步化的全部意义。

相反,你的回调函数应该在完成后使用分派器回调UI线程。注意,您还应该有健壮的错误处理,以防请求出现任何错误。

与回答问题不完全相关,但答案块似乎是适合我即将提出的建议的唯一地方…通过使用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("answersJson 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("answersJson from responseCallback {0}", ansJson);
        }

我还建议用try..catch块包围reqresp操作,以允许某些东西处理异常条件-否则它将冒气泡到AppDomain的异常处理程序(也可以通过UnhandledException事件挂钩)。