我正在尝试开发Windows Phone 7应用程序。此应用程序的一部分包括联系API以检索某些数据。为此,我正在使用HTTPWebRequest和我编写的一个小助手类;我调用HTTPHelper的sendAPIRequest,然后检索结果。
问题在于异步请求启动后的执行链。通过我的调试,我发现调用了BeginGetRequestStream的回调requestCallBack。此回调随后调用BeginGetResponse及其回调;不幸的是,它的回调(responseCallBack)永远不会触发。我已经确定永远不会联系API所在的服务器(Apache的日志中没有任何内容),并且在执行request.BeginGetResponse之后,调试器会显示一个空的本地列表和一个空堆栈;永远不会触发回调,程序无处可去。我已经尝试过所有可以想到的调试类型,但我现在已经结束了。没有异常被抛出,没有任何东西看起来 - 程序只是无法联系服务器并继续。
这是我正在使用的代码:
public class HTTPHelper
{
public string postString { get; set; }
public string responseData { get; set; }
private static ManualResetEvent readyToGo = new ManualResetEvent(false);
public void sendAPIRequest(string mode, string data)
{
GenericAPIRequest requestInformation = new GenericAPIRequest { data = data, device_id = getDeviceId(), method = mode };
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://192.168.1.69/api/master.php?source=client");
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
string postData = "device_id=" + getDeviceId() + "&data=" + JsonConvert.SerializeObject(requestInformation) + "&mode=" + mode;
postString = postData;
request.BeginGetRequestStream(new AsyncCallback(requestCallBack), request);
// Stop the thread until we've finished our HTTP request
readyToGo.WaitOne();
return;
}
private void requestCallBack(IAsyncResult asynchronousResult)
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
Stream postStream = request.EndGetRequestStream(asynchronousResult);
byte[] postBytes = Encoding.UTF8.GetBytes(postString);
postStream.Write(postBytes, 0, postString.Length);
postStream.Close();
request.BeginGetResponse(new AsyncCallback(responseCallBack), request);
return;
}
private void responseCallBack(IAsyncResult asynchronousResult)
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
Stream streamResponse = response.GetResponseStream();
StreamReader streamRead = new StreamReader(streamResponse);
responseData = streamRead.ReadToEnd();
streamResponse.Close();
streamRead.Close();
response.Close();
// Release the thread...
readyToGo.Set();
return;
}
private string getDeviceId()
{
// Gets the unique device ID, allows us to track the device.
byte[] result = null;
object uniqueId;
if (DeviceExtendedProperties.TryGetValue("DeviceUniqueId", out uniqueId))
result = (byte[])uniqueId;
return System.BitConverter.ToString(result);
}
private static ManualResetEvent readyToGo = new ManualResetEvent(false);
public void sendAPIRequest(string mode, string data)
{
GenericAPIRequest requestInformation = new GenericAPIRequest { data = data, device_id = getDeviceId(), method = mode };
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://192.168.1.69/api/master.php?source=client");
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
string postData = "device_id=" + getDeviceId() + "&data=" + JsonConvert.SerializeObject(requestInformation) + "&mode=" + mode;
postString = postData;
request.BeginGetRequestStream(new AsyncCallback(requestCallBack), request);
// Stop the thread until we've finished our HTTP request
readyToGo.WaitOne();
return;
}
private void requestCallBack(IAsyncResult asynchronousResult)
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
Stream postStream = request.EndGetRequestStream(asynchronousResult);
byte[] postBytes = Encoding.UTF8.GetBytes(postString);
postStream.Write(postBytes, 0, postString.Length);
postStream.Close();
request.BeginGetResponse(new AsyncCallback(responseCallBack), request);
return;
}
private void responseCallBack(IAsyncResult asynchronousResult)
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
Stream streamResponse = response.GetResponseStream();
StreamReader streamRead = new StreamReader(streamResponse);
responseData = streamRead.ReadToEnd();
streamResponse.Close();
streamRead.Close();
response.Close();
// Release the thread...
readyToGo.Set();
return;
}
private string getDeviceId()
{
// Gets the unique device ID, allows us to track the device.
byte[] result = null;
object uniqueId;
if (DeviceExtendedProperties.TryGetValue("DeviceUniqueId", out uniqueId))
result = (byte[])uniqueId;
return System.BitConverter.ToString(result);
}
关于这里做错了什么的任何建议?
感谢您提出的所有建议。
答案 0 :(得分:2)
尝试拔出readyToGo.WaitOne()。这将导致线程停止并等待信号。请求可能需要在该线程上进行处理,因此不会被调用。
奇怪的是,几分钟前我遇到了与重置事件非常类似的问题,尽管它是使用WPF而不是HttpRequests :)。
顺便说一句,我在CodePlex上有一个代码参考库,其中包含一个HttpWebRequest帮助程序(它可能不会直接帮助你,只是想我会提到它)。你可以随意使用它(甚至只是为了获取你喜欢的部分代码)。该项目名为BizArk,该类称为WebHelper。