C# 将HttpWebRequest与async和Wait一起使用
我刚开始使用C#,所以请原谅我对如何使用它的无知(如果有的话)。 我有一个登录按钮,它执行以下代码C# 将HttpWebRequest与async和Wait一起使用,c#,windows-phone-8,httpwebrequest,async-await,C#,Windows Phone 8,Httpwebrequest,Async Await,我刚开始使用C#,所以请原谅我对如何使用它的无知(如果有的话)。 我有一个登录按钮,它执行以下代码 private void Login_Click(object sender, RoutedEventArgs e) { if (email_box.Text != "" && password_box.Password != "") { string strRegex = @"^([a-zA-Z0-9_\-\.]+)@((\[[0-
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";
}
}
该方法初始化该类,并调用初始化_请求(),该函数在内部调用GetRequestStreamCallback,该函数也调用GetResponseStreamCallback
初始化请求应该发回一个字符串,该字符串在GetResponseStreamCallBack中设置,但它似乎在最后两个方法执行之前发回一个字符串。
Soo,我读过关于async和await的文章,我也尝试过使用它们,但是Visual Studio说不能等待“方法组”,我把等待放在那里
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());
}
}
}
}
现在的问题是,GetResponsetStreamCallback从未启动,看起来我从未返回,因为
Debug.WriteLine(“我们返回了吗?”)代码>永远不会执行 < P>如Stephen Cleary所提到的,因为您正在构建Windows Phone 8,请考虑使用<代码> HTTPcli客< /代码>,而不是<代码> HttpWebRequest < /Cord>类。这背后的原因不仅仅是“容易得多”
如VS论坛所述:
HttpClient
更像是一款无头浏览器。它是一个强有力的
如果要创建多个http请求,这是一个理想的工具。对于
例如,您可以设置默认的标题和内容。以下是五大方法
它与HttpWebRequest不同:
HttpClient
实例是配置扩展、设置
默认标题、取消未完成的请求等
您可以通过单个HttpClient
实例发出任意数量的请求李>
HttpClient不绑定到特定的HTTP服务器或主机;您可以使用相同的HttpClient
实例提交任何HTTP请求
您可以从HttpClient
派生,为特定站点或模式创建专门的客户端
HttpClient
使用新的面向任务的模式来处理异步请求,从而大大简化了管理和维护
协调多个未完成的请求
欲了解更多信息,请阅读全文并参考此
有几个例子和完整的项目展示了如何以不同的方式使用HttpClient
,不仅可以加载字符串,还可以从JSON对象创建c对象。不需要GetRequestStreamCallback方法异步。将其签名更改为private void GetRequestStreamCallback(IAsyncResult callbackResult)@VictorMukherjee我已经尝试过了,但仍然是'Debug.WriteLine(“我们返回了吗?”);'在两个方法中的任何一个之前执行!另外,如果要使用异步模型.Debug.WriteLine(“我们返回了吗?”),那么您可能需要使用request.GetRequestStreamAsync;在大多数情况下,将在这两个方法之前执行,因为request.BeginGetRequestStream方法是异步执行的,但由于它不使用任何async关键字,因此不能等待任务。但是,您可以在开始eTRequestStream后使用AutoResteEvent等待initialize_请求方法,并从GetResponsetStreamCallback设置AutoResteEvent。@VictorMukherjee我已经尝试过AutoResteEvent,请参阅更新的问题!谢谢。我将调查HttpClient
将对此给出反馈!尽管如此,我更感兴趣的是一个解决我目前状况的方案,然后是替代方案。我完全理解你的意思,只是我觉得使用过时的东西是不对的。检查:我已经转到HttpClient
,它正在做这项工作,在多次尝试修复问题失败后,它将把代码推送到git hub并在此处共享链接。谢谢你的推荐
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();
}
}
}