我刚开始使用C#,请原谅我如何使用它的无知(如果有的话)。 我有一个登录按钮,执行以下代码
private void Login_Click(object sender, RoutedEventArgs e)
{
if (email_box.Text != "" && password_box.Password != "") {
string strRegex = @"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}" + @"\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\" + @".)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$";
Regex reg = new Regex(strRegex);
if (reg.IsMatch(email_box.Text))
{
ApiCall request = new ApiCall();
request.requestData = "{\"sessions\": {\"links\":{\"user\":{\"email\":\"" + email_box.Text + "\",\"password\":\"" + password_box.Password + "\" }}}}";
request.requestMethod = Constants.httpMethods[0];
request.resource_url = "/sessions";
var response = request.initialize_request();
//Once i get the response string, i will deserialize it here and use it to do other things, like navigate to a new page an any other neccessary things to do!
}
else
{
recover.Text = "Please provide a valid email address.";
}
}
else
{
recover.Text = "Email and Password cannot be Empty";
}
}
该方法初始化此类并调用 initialize_request(),其内部调用 GetRequestStreamCallback ,它也调用 GetResponseStreamCallback 。
Intialize请求应该发回一个字符串,该字符串在 GetResponseStreamCallBack 中设置但看起来,它在最后两个方法执行之前发回一个字符串。 Soo,我读到了异步和等待,我试图使用它们,但Visual Studio说无法等待&#34;方法组&#34; < / strong>我把等待
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Diagnostics;
using System.Net;
using Newtonsoft.Json;
using PrintMyPic.ApiJsonObjects;
using PrintMyPic;
using System.Windows.Navigation;
namespace MyApp
{
class ApiCall
{
public static string api_url = "http://myappsapiurl/api";
public static string content_type = "application/vnd.api+json";
public string requestData;
public string requestMethod;
public string resource_url; // the rest of the api url
public string requestResponse;
public async Task<string> initialize_request()
{
Debug.WriteLine("the resource used is "+ resource_url);
System.Uri myUri = new System.Uri(api_url+resource_url);
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(myUri);
request.ContentType = content_type;
request.Method = requestMethod;
request.Accept = content_type;
request.BeginGetRequestStream(new AsyncCallback(await GetRequestStreamCallback), request);
Debug.WriteLine("have we returned yet?");
return requestResponse;
}
private async Task GetRequestStreamCallback(IAsyncResult callbackResult)
{
Debug.WriteLine("we are in the second method");
HttpWebRequest webrequest = (HttpWebRequest)callbackResult.AsyncState;
Stream postStream = webrequest.EndGetRequestStream(callbackResult);
byte[] byteArray = Encoding.UTF8.GetBytes(requestData);
postStream.Write(byteArray, 0, byteArray.Length);
postStream.Close();
webrequest.BeginGetResponse(new AsyncCallback( await GetResponsetStreamCallback), webrequest);
}
private void GetResponsetStreamCallback(IAsyncResult callbackResult)
{
Debug.WriteLine("we are in the third method");
try
{
HttpWebRequest request = (HttpWebRequest)callbackResult.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(callbackResult);
string responseString = "";
Stream streamResponse = response.GetResponseStream();
StreamReader reader = new StreamReader(streamResponse);
responseString = reader.ReadToEnd();
streamResponse.Close();
reader.Close();
response.Close();
requestResponse = responseString;
}
catch (Exception e)
{
//show user-friendly error message as well as detailed one.
//for better UI, consider using WPToolKit's CustomMessageBox to show these
Debug.WriteLine("something wrong happened. \nDetails: " + e.HResult.ToString());
}
}
}
}
Anyhelp修复此问题非常感谢,我希望 intialize_request()执行,等待 GetRequestStreamCallback 和 GetResponseStreamCallback 完成,然后返回 requestResponse
[更新] 根据评论部分,我被建议使用 AutoResetEvent
namespace MyApp
{
class ApiCall
{
public static string api_url = "http://myappapirul/api";
public static string content_type = "application/vnd.api+json";
public string requestData;
public string requestMethod;
public string resource_url; // the rest of the api url
public string requestResponse;
public static AutoResetEvent objAuto = new AutoResetEvent(false);
public string initialize_request()
{
Debug.WriteLine("the resource used is "+ resource_url);
System.Uri myUri = new System.Uri(api_url+resource_url);
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(myUri);
request.ContentType = content_type;
request.Method = requestMethod;
request.Accept = content_type;
request.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), request);
objAuto.WaitOne();
Debug.WriteLine("have we returned yet?");
return requestResponse;
}
private void GetRequestStreamCallback(IAsyncResult callbackResult)
{
Debug.WriteLine("we are in the second method");
HttpWebRequest webrequest = (HttpWebRequest)callbackResult.AsyncState;
Stream postStream = webrequest.EndGetRequestStream(callbackResult);
byte[] byteArray = Encoding.UTF8.GetBytes(requestData);
postStream.Write(byteArray, 0, byteArray.Length);
postStream.Close();
webrequest.BeginGetResponse(new AsyncCallback(GetResponsetStreamCallback), webrequest);
}
private void GetResponsetStreamCallback(IAsyncResult callbackResult)
{
Debug.WriteLine("we are in the third method");
try
{
HttpWebRequest request = (HttpWebRequest)callbackResult.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(callbackResult);
string responseString = "";
Stream streamResponse = response.GetResponseStream();
StreamReader reader = new StreamReader(streamResponse);
responseString = reader.ReadToEnd();
streamResponse.Close();
reader.Close();
response.Close();
requestResponse = responseString;
}
catch (Exception e)
{
//show user-friendly error message as well as detailed one.
//for better UI, consider using WPToolKit's CustomMessageBox to show these
Debug.WriteLine("something wrong happened. \nDetails: " + e.HResult.ToString());
}
Debug.WriteLine("we are about to return to initialize_request");
objAuto.Set();
}
}
}
现在的问题是, GetResponsetStreamCallback 永远不会启动,看起来我永远不会回来,因为Debug.WriteLine("have we returned yet?");
永远不会被执行!
答案 0 :(得分:1)
就像Stephen Cleary所提到的那样,既然您正在为Windows Phone 8构建,请考虑使用HttpClient
而不是HttpWebRequest
类。这背后的原因不仅仅是这样,而且更容易&#34;。
如VS论坛所述:
不同
HttpClient
更像是无头浏览器。它是一个强大的和 如果您要创建许多http请求,这是理想的工具。对于 例如,您可以设置默认标题和内容。以下是前5种方式 它与HttpWebRequest
:
HttpClient
实例是配置扩展名的地方 默认标题,取消未完成的请求等。- 您可以通过单个
HttpClient
实例发出任意数量的请求。HttpClients不依赖于特定的HTTP服务器或主机;您可以使用相同的
HttpClient
实例提交任何HTTP请求。您可以从
HttpClient
派生,为特定网站或模式创建专门的客户- 醇>
HttpClient
使用新的面向任务的模式来处理异步请求,使其更易于管理和管理 协调多个未完成的请求。
有几个示例和完整项目展示了如何以不同方式使用HttpClient
,而不仅仅是加载字符串,还要从JSON对象创建c#对象。