C# 后提交者的异步CTP
我正在尝试使用异步CTP构建REST客户机。我是CTP的新手,因此,在浏览了互联网上的许多示例后,我得到了一个只用于发布(GET或POST)的clas。以下是到目前为止的课程:C# 后提交者的异步CTP,c#,winforms,c#-4.0,asynchronous,async-await,C#,Winforms,C# 4.0,Asynchronous,Async Await,我正在尝试使用异步CTP构建REST客户机。我是CTP的新手,因此,在浏览了互联网上的许多示例后,我得到了一个只用于发布(GET或POST)的clas。以下是到目前为止的课程: using System; using System.Collections.Specialized; using System.IO; using System.Net; using System.Text; using System.Threading.Tasks; using System.Web; namesp
using System;
using System.Collections.Specialized;
using System.IO;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Web;
namespace RESTClient.Core {
/// <summary>
/// Submits post data to a url.
/// </summary>
public class PostSubmitter {
#region Backing Store
private string m_url = string.Empty;
private NameValueCollection m_values = new NameValueCollection();
private PostTypeEnum m_type = PostTypeEnum.Get;
#endregion
#region Constructors
/// <summary>
/// Default constructor.
/// </summary>
public PostSubmitter() {
}
/// <summary>
/// Constructor that accepts a url as a parameter
/// </summary>
/// <param name="url">The url where the post will be submitted to.</param>
public PostSubmitter(string url)
: this() {
m_url = url;
}
/// <summary>
/// Constructor allowing the setting of the url and items to post.
/// </summary>
/// <param name="url">the url for the post.</param>
/// <param name="values">The values for the post.</param>
public PostSubmitter(string url, NameValueCollection values)
: this(url) {
m_values = values;
}
#endregion
#region Properties
/// <summary>
/// Gets or sets the url to submit the post to.
/// </summary>
public string Url {
get {
return m_url;
}
set {
m_url = value;
}
}
/// <summary>
/// Gets or sets the name value collection of items to post.
/// </summary>
public NameValueCollection PostItems {
get {
return m_values;
}
set {
m_values = value;
}
}
/// <summary>
/// Gets or sets the type of action to perform against the url.
/// </summary>
public PostTypeEnum Type {
get {
return m_type;
}
set {
m_type = value;
}
}
#endregion
/// <summary>
/// Posts the supplied data to specified url.
/// </summary>
/// <returns>a string containing the result of the post.</returns>
public async Task<String> Post() {
StringBuilder parameters = new StringBuilder();
for (int i = 0; i < m_values.Count; i++) {
EncodeAndAddItem(ref parameters, m_values.GetKey(i), m_values[i]);
}
string result = await PostData(m_url, parameters.ToString());
return result;
}
/// <summary>
/// Posts the supplied data to specified url.
/// </summary>
/// <param name="url">The url to post to.</param>
/// <returns>a string containing the result of the post.</returns>
public async Task<String> Post(string url) {
m_url = url;
return await this.Post();
}
/// <summary>
/// Posts the supplied data to specified url.
/// </summary>
/// <param name="url">The url to post to.</param>
/// <param name="values">The values to post.</param>
/// <returns>a string containing the result of the post.</returns>
public async Task<String> Post(string url, NameValueCollection values) {
m_values = values;
return await this.Post(url);
}
/// <summary>
/// Posts data to a specified url. Note that this assumes that you have already url encoded the post data.
/// </summary>
/// <param name="postData">The data to post.</param>
/// <param name="url">the url to post to.</param>
/// <returns>Returns the result of the post.</returns>
private async Task<String> PostData(string url, string postData) {
HttpWebRequest request = null;
if (m_type == PostTypeEnum.Post) {
Uri uri = new Uri(url);
request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = postData.Length;
using (Stream writeStream = await request.GetRequestStreamAsync()) {
UTF8Encoding encoding = new UTF8Encoding();
byte[] bytes = encoding.GetBytes(postData);
writeStream.Write(bytes, 0, bytes.Length);
}
}
else {
Uri uri = new Uri(url + "?" + postData);
request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "GET";
}
string result = string.Empty;
using (HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync()) {
using (Stream responseStream = response.GetResponseStream()) {
using (StreamReader readStream = new StreamReader(responseStream, Encoding.UTF8)) {
result = readStream.ReadToEnd();
}
}
}
return result;
}
/// <summary>
/// Encodes an item and ads it to the string.
/// </summary>
/// <param name="baseRequest">The previously encoded data.</param>
/// <param name="dataItem">The data to encode.</param>
/// <returns>A string containing the old data and the previously encoded data.</returns>
private void EncodeAndAddItem(ref StringBuilder baseRequest, string key, string dataItem) {
if (baseRequest == null) {
baseRequest = new StringBuilder();
}
if (baseRequest.Length != 0) {
baseRequest.Append("&");
}
baseRequest.Append(key);
baseRequest.Append("=");
baseRequest.Append(HttpUtility.UrlEncode(dataItem));
}
}
}
尝试以下方法:
private async void ButtonSubmit_Click(object sender, EventArgs e) {
ButtonReset.Enabled = false;
TextResponse.Text = String.Empty;
TextResponse.Text += "Begining..." + Environment.NewLine;
TextResponse.Text += await PostSomeData();
TextResponse.Text += Environment.NewLine;
TextResponse.Text += "Function Done!" + Environment.NewLine;
}
您需要在客户端中使用
async
和wait
关键字。改变这两行,你应该很好:
private void ButtonSubmit_Click(object sender, EventArgs e) {
=>
private async void ButtonSubmit_Click(object sender, EventArgs e) {
TextResponse.Text += Task.Factory.StartNew(() => PostSomeData().Wait());
=>
TextResponse.Text += await PostSomeData();
您的代码只是部分异步的;请仔细查看
PostData
特别是,ReadToEnd
需要异步:
private async Task<String> PostData(string url, string postData)
{
HttpWebRequest request = null;
if (m_type == PostTypeEnum.Post)
{
Uri uri = new Uri(url);
request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = postData.Length;
using (Stream writeStream = await request.GetRequestStreamAsync())
{
UTF8Encoding encoding = new UTF8Encoding();
byte[] bytes = encoding.GetBytes(postData);
await writeStream.WriteAsync(bytes, 0, bytes.Length);
}
}
else
{
Uri uri = new Uri(url + "?" + postData);
request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "GET";
}
using (HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync())
using (Stream responseStream = response.GetResponseStream())
using (StreamReader readStream = new StreamReader(responseStream, Encoding.UTF8))
{
return await readStream.ReadToEndAsync();
}
}
private async Task PostData(字符串url,字符串PostData)
{
HttpWebRequest请求=null;
if(m_type==PostTypeEnum.Post)
{
Uri=新的Uri(url);
request=(HttpWebRequest)WebRequest.Create(uri);
request.Method=“POST”;
request.ContentType=“application/x-www-form-urlencoded”;
request.ContentLength=postData.Length;
使用(Stream writeStream=wait request.GetRequestStreamAsync())
{
UTF8Encoding=新的UTF8Encoding();
字节[]字节=编码.GetBytes(postData);
wait writeStream.WriteAsync(字节,0,字节.长度);
}
}
其他的
{
Uri=新Uri(url+“?”+postData);
request=(HttpWebRequest)WebRequest.Create(uri);
request.Method=“GET”;
}
使用(HttpWebResponse=(HttpWebResponse)wait request.GetResponseAsync())
使用(Stream responseStream=response.GetResponseStream())
使用(streamreadstream=newstreamreader(responseStream,Encoding.UTF8))
{
返回wait wait readStream.ReadToEndAsync();
}
}
正如其他人所提到的,这是除了使事件处理程序异步之外的另一项功能。这确实解决了这个问题。但是,仅当类型为GET时。此外,用户界面frooze。我不能让用户界面冻结。。。有什么建议吗?仅供参考,
m
变量前缀被认为在.NET命名中使用是错误的。^完全同意。这是一些小朋友写的。一旦我把事情弄清楚,我就解雇他。他只是高兴地回家说“一切都结束了”。。。我想知道为什么UI挂起了?好的。似乎包括POST方法在内的一切都在运行。谢谢
private void ButtonSubmit_Click(object sender, EventArgs e) {
=>
private async void ButtonSubmit_Click(object sender, EventArgs e) {
TextResponse.Text += Task.Factory.StartNew(() => PostSomeData().Wait());
=>
TextResponse.Text += await PostSomeData();
private async Task<String> PostData(string url, string postData)
{
HttpWebRequest request = null;
if (m_type == PostTypeEnum.Post)
{
Uri uri = new Uri(url);
request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = postData.Length;
using (Stream writeStream = await request.GetRequestStreamAsync())
{
UTF8Encoding encoding = new UTF8Encoding();
byte[] bytes = encoding.GetBytes(postData);
await writeStream.WriteAsync(bytes, 0, bytes.Length);
}
}
else
{
Uri uri = new Uri(url + "?" + postData);
request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "GET";
}
using (HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync())
using (Stream responseStream = response.GetResponseStream())
using (StreamReader readStream = new StreamReader(responseStream, Encoding.UTF8))
{
return await readStream.ReadToEndAsync();
}
}