这是我的代码:
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,而是tryis userId.Text指定asnJson值为null,因为它没有进入ResponseCallback。当我做错了,为什么它永远不会进入ResponseCallback?
答案 0 :(得分:2)
您的ManualResetEvent
是以true
为参数创建的,所以它已经开始发出信号。这意味着allDone.Wait()
调用会立即继续...所以CreateRequest
将完成,您立即尝试使用asnJson
变量,就像您一样我说的是null
。我怀疑这会扼杀申请 - 所以你永远不会有机会得到答复。
现在,对此的解决方案是而不是来更改ManualResetEvent
构造函数 - 你不应该像在UI线程中那样等待!你会阻止它,你已经删除了Windows Phone 7的全部内容,使一切都以异步开始。
相反,您的回调应该使用调度程序在完成后回调到UI线程。请注意,如果请求出现任何问题,您还应该具有强大的错误处理功能。
答案 1 :(得分: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事件挂钩。