为什么没有调用 BeginGetResponse 回调?

发布于 2024-12-08 16:07:37 字数 2780 浏览 0 评论 0原文

这是我的代码:

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': '[email protected]', '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,而是尝试使用 userId.Text 来分配为 null 的 asnJson 值,因为它不输入 ResponseCallback。当我做错了,为什么它永远不会进入ResponseCallback?

Here's my code:

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': '[email protected]', '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();

        }
    }
}

When I debug application it entered CreateRequest then it enter RequestCallback, but then it stop and never enter ResponseCallback instead it tryis userId.Text to assign asnJson value which is null, because it doesn't enter ResponseCallback. When I do wrong, and why it never enter ResponseCallback?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

温柔戏命师 2024-12-15 16:07:37

您的 ManualResetEvent 是使用 true 作为参数创建的,因此它已经发出开始的信号。这意味着 allDone.Wait() 调用将立即继续...因此 CreateRequest 将完成,并且您将立即尝试使用asnJson 变量,正如您所说,它是 null。我怀疑这会杀死应用程序 - 所以你永远没有机会得到回应。

现在,解决此问题的方法是更改 ManualResetEvent 构造函数 - 无论如何,您不应该像这样在 UI 线程中等待!您将阻止它,并且您已经删除了 Windows Phone 7 使所有内容从一开始就异步的全部要点。

相反,您的回调应该在完成后使用调度程序回调到 UI 线程。请注意,您还应该具有强大的错误处理能力,以防请求出现任何问题。

Your ManualResetEvent is created with true as the argument, so it's already signalled to start with. That means the allDone.Wait() call will immediately continue... so CreateRequest will finish, and you'll immediately try to use the asnJson variable, which as you've said is null. That will kill the application, I suspect - so you never get a chance to get a response.

Now, the solution to this is not to change the ManualResetEvent constructor - you shouldn't be waiting like that in the UI thread anyway! You'll block it, and you've removed the whole point of Windows Phone 7 making everything asynchronous to start with.

Instead, your callbacks should use the dispatcher to call back into the UI thread when they've finished. Note that you should also have robust error handling in case anything goes wrong with the request.

ˉ厌 2024-12-15 16:07:37

与回答问题并不完全相关,但答案块似乎是唯一适合我即将提出的建议的地方...您应该通过使用 using 在流周围提供适当的资源保护块如下:

原始代码:

        Stream postStream = req.EndGetRequestStream(aresult);

        string obj = "{ 'username': '[email protected]', '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)< /strong>) :

        using (Stream postStream = req.EndGetRequestStream(aresult))
        {
            string obj = "{ 'username': '[email protected]', '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);
        }

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

Not exactly related to answering the question, but an answer block seems to be the only place to fit the recommendation I'm about to make... You should have appropriate resource protection around your streams by employing using blocks as such:

Original code:

        Stream postStream = req.EndGetRequestStream(aresult);

        string obj = "{ 'username': '[email protected]', '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();

New code (also make sure your encoding is correct for the request: is your web service really expecting UTF-16? It's more common that web servers use UTF-8 (Encoding.UTF8)) :

        using (Stream postStream = req.EndGetRequestStream(aresult))
        {
            string obj = "{ 'username': '[email protected]', '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);
        }

Original code:

        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();

New code:

        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);
        }

I would also recommend surrounding your req and resp operations with try..catch blocks to allow something to process exceptional conditions -- otherwise it will bubble up to the AppDomain's exception handler (can also be hooked by the UnhandledException event).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文