.net 异步编程小结
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Test
{
public class MyMain
{
public delegate void Show();
public delegate int Get(int key);
/// <summary>
/// .net4.5之前实现异步编程的四种方式(用BeginInvoke和EndInvoke实现)
/// </summary>
/// BeginInvoke 返回值可以判断异步是否执行完毕, 后两个参数第一个为回调方法,第二个为调用委托本身,前面的参数为调用委托的参数
/// EndInvoke 返回值为调用委托的返回值
static void show1()
{
Console.WriteLine("异步执行开始...");
for (int i = 0; i < 200; i++)
{
Console.WriteLine(i);
}
Console.WriteLine("异步执行完毕...");
}
static int get(int key)
{
return key * 10;
}
/// <summary>
/// .net4.5开始使用async和await进行异步编程
/// </summary>
/// 一个async方法里通常包含一个或多个的对应的await操作符,
/// 但如果没有await表达式也不会导致编译错误。
/// 但如果调用一个async方 法,
/// 却不使用await关键字来标记一个挂起点的话,
/// 程序将会忽略async关键字并以同步的方式执行
async static Task<int> show3(int key)
{
Console.WriteLine("异步执行开始...");
await Task.Delay(5000); //表示5秒后继续执行异步线程
for (int i = 0; i < 100; i++)
{
Console.WriteLine(i);
}
Console.WriteLine("异步执行完毕...");
return key * 10;
}
static void Main()
{
//第一种方法:BeginEnvoke EndEnvoke方法,属于“等待”类。
/*
Show show = show1;
Console.WriteLine("主线程执行开始...");
IAsyncResult result = show.BeginInvoke(null, null);
Console.WriteLine("主线程继续执行...");
for (int i = 0; i < 100; i++)
{
Console.WriteLine(i * -1);
}
show.EndInvoke(result);//在这之前可以同时执行异步线程和主线程,在这之后异步线程结束,这行代码之后的行为才能开始执行,意思就是这行代码之后的行为需要等待异步线程执行完毕才能执行
Console.WriteLine("主线程执行结束...");
*/
//第二种方法:WaitOne。同样属于“等待”类。
/*
Show show = show1;
Console.WriteLine("主线程执行开始...");
IAsyncResult result = show.BeginInvoke(null, null);
Console.WriteLine("主线程继续执行...");
for (int i = 0; i < 100; i++)
{
Console.WriteLine(i * -1);
}
result.AsyncWaitHandle.WaitOne(); //WaitOne方法有多重重载体,具体查阅MSDN
Console.WriteLine("主线程执行结束...");
*/
//第三种方法:轮询。也是属于“等待”类。
/*
Show show = show1;
Console.WriteLine("主线程执行开始...");
IAsyncResult result = show.BeginInvoke(null, null);
Console.WriteLine("主线程继续执行...");
while(!result.IsCompleted)//可以在异步线程执行完毕之前做些事情
{
Console.WriteLine("...");
Thread.Sleep(1000);
}
Console.WriteLine("主线程执行完毕...");
*/
//第四种方法:回调。当然属于“回调”类.
//异步方法没有返回值
/*
Show show = show1;
Console.WriteLine("主线程开始执行...");
show.BeginInvoke(callback1, show);
Console.WriteLine("主线程执行完毕...");
*/
/*
//异步方法有返回值
Get get_ = get;
get_.BeginInvoke(1, callback2, get_);
*/
//第五种方法:使用async 和 await 关键字 可以使异步使用像平常方法那样简单
Console.WriteLine("主线程执行开始...");
var tmp = show3(1);
Console.WriteLine("主线程继续执行...");
for (int i = 0; i < 100; i++)
{
Console.WriteLine(i * -1);
}
Console.WriteLine("主线程执行完毕...");
Console.WriteLine(tmp.Result);
Console.ReadKey();
}
//回调方法要求
//1.返回类型为void
//2.只有一个参数IAsyncResult
static void callback1(IAsyncResult result)
{
(result.AsyncState as Show).EndInvoke(result);
Console.WriteLine("异步线程执行已经完毕");
}
static void callback2(IAsyncResult result)
{
int key = ((Get)result.AsyncState).EndInvoke(result);
Console.WriteLine(key);
}
}
}