本人新手,自学C#,做过一些小项目,以前多线程用的都是Thread、backgroudworker,后来要搞一个tcp服务器,就开始学异步编程,正好看到基于任务的异步模型,在网上看了很多例子,讲的都不是很清楚,正好手上有C#高级编程第十版,看了看书又结合网上的只是,自己把原来的同步代码,改成了异步。
。Net4.5提供了基于任务的异步模式(TAP),该模式定义了一个带有“Async”后缀的方法,并返回一个Task类型。await关键字会解除UI线程的阻塞,完成其他任务,当带有Async后缀的方法完成后台处理后,UI线程就可以继续,从后台任务中获取结果。
HttpPost请求函数
/// <summary>
/// HTTP POST请求
/// </summary>
/// <param name="Url">URL地址</param>
/// <param name="postDataStr">参数字符串</param>
/// <returns>返回结果</returns>
public string HttpPost(string Url, string postDataStr = "")
{
string responseData = "";
HttpWebResponse response;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = postDataStr.Length;
request.Timeout = 1000;
try
{
byte[] bs = Encoding.ASCII.GetBytes(postDataStr);
Stream reqStream = request.GetRequestStream();
reqStream.Write(bs, 0, bs.Length);
reqStream.Close();
response = (HttpWebResponse)request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
responseData = reader.ReadToEnd().ToString();
reader.Close();
request.Abort();
response.Close();
}
catch (Exception ee)
{
responseData = ee.ToString();
}
return responseData;
}
做一个按钮调用(同步方法,点击事件知道UI线程更新后才能拖动界面,阻塞的)
/// <summary>
/// 按钮事件。请求结果。UI堵塞
/// </summary>
/// <param name="sender">按钮</param>
/// <param name="e"></param>
private void button2_Click(object sender, EventArgs e)
{
this.textBox2.Text = HttpPost(this.textBox1.Text);
}
我们将HttpPOST改成基于任务的异步编程
/// <summary>
/// 异步请求,返回请求结果
/// </summary>
/// <param name="Url">请求地址</param>
/// <returns>参数列表</returns>
public async Task<string> GetHttpPostStringAsync(string Url)
{
return await Task.Run<string>(() =>
{
return HttpPost(Url);
});
//Invoke(new Action(() => { }));
//Action<int> act = new Action<int>((i) => { i=i + 1; });
//Func<int, string> func = new Func<int, string>((i) =>
// {
// return (i + 1).ToString();
// });
}
调用:
/// <summary>
/// 按钮事件,异步事件,获取结果,非UI堵塞
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void button1_Click(object sender, EventArgs e)
{
string getstr=await GetHttpPostStringAsync(this.textBox1.Text);
this.textBox2.Text=getstr;
}
阻塞的就变成非阻塞的了,Task在线程池里面运行,没有阻塞,也不需要切换回UI线程,这些都是自动实现的。