下面是我的代码:
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,而是尝试使用userId.Text来赋值为空的asnJson值,因为它没有输入ResponseCallback。当我做错的时候,为什么它从来不进入ResponseCallback?
发布于 2011-10-06 16:48:42
您的ManualResetEvent
是以true
作为参数创建的,因此它已经发出了开始的信号。这意味着allDone.Wait()
调用将立即继续...因此CreateRequest
将完成,您将立即尝试使用asnJson
变量,正如您所说的,该变量是null
。我怀疑这会杀死应用程序--所以你永远没有机会得到响应。
现在,解决这个问题的方法不是改变ManualResetEvent
构造函数--你不应该像那样在UI线程中等待!你将阻止它,并且你已经移除了Windows phone7让所有东西都是异步的。
相反,您的回调应该在完成时使用dispatcher回调到UI线程。请注意,您还应该有健壮的错误处理,以防请求出现任何错误。
发布于 2011-10-06 17:52:08
与回答问题无关,但答案块似乎是唯一适合我即将提出的建议的地方……您应该通过使用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服务真的需要UTF16吗?更常见的是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事件挂钩)。
https://stackoverflow.com/questions/7677665
复制相似问题