1.概要
异步函数如何才能真正的发挥出线程的优势,异步函数执行期间,调用该函数的线程可以继续工作,这才是异步的真正价值。如下做了几个实验,无论是采用异步函数的方式,还是利用task,理想的方式都是采用回调的方式。对于异步函数的返回值,最理想的处理方式还是采用回调。
概要举例
1.1 异步函数
回调:IAsyncResult iar = da.BeginInvoke(6, goBack, null);
等待:IAsyncResult iar = da.BeginInvoke(6, null, null);
var ret = da.EndInvoke(iar);
轮询: IAsyncResult iar = da.BeginInvoke(6, null, null);
while (true) {
if (iar.IsCompleted) {
var ret = da.EndInvoke(iar);
}
}
1.2 task
回调: Task<int> t = new Task<int>(fun,6);
taw = t.GetAwaiter();
taw.OnCompleted(goBack);
t.Start();
等待1: Task<int> t = new Task<int>(fun, 6);
t.Start();
int a = await t;
等待2: Task<int> t = new Task<int>(fun, 6);
t.Start();
t.Wait();
int a = t.Result;
轮询:Task<int> t = new Task<int>(fun, 6);
t.Start();
while (true) {
if (t.IsCompleted) {
int a = t.Result;
}
}
2.代码
using System;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
namespace 线程效率发挥实验
{
/// <summary>
/// 把一个处理交给一个线程处理
/// 如果再这个线程等待返回结果,那么没有任何意义
/// 最好给他一个返回的处理函数
/// </summary>
class Program
{
static void Main(string[] args)
{
Console.WriteLine("线程效率发挥实验");
异步实验();
//任务实验();
Console.ReadKey();
}
static void 异步实验() {
run<异步线程回调>();
run<异步线程等待>();
run<异步线轮询>();
}
static void 任务实验() {
run<任务回调>();
run<任务等待>();
run<任务等待2>();
run<任务轮询>();
}
static void run<T>() where T : 接口, new()
{
Console.WriteLine(typeof(T).Name + ":开始---------------------------------------");
new T().main();
Console.WriteLine(typeof(T).Name + ":结束---------------------------------------");
Console.WriteLine();
}
}
public interface 接口 {
void main();
}
public delegate void DePrint();
abstract public class 基类: 接口
{
public void WriteLine(string str) {
Console.WriteLine(Thread.CurrentThread.ManagedThreadId+":"+this.GetType().Name+":"+str);
}
protected abstract void myMain();
public void main()
{
WriteLine("main 开始");
myMain();
WriteLine("main 结束");
}
protected void printThread() {
WriteLine(this.GetType().Name+":main");
}
}
public delegate int DelegateAdd(int a);
class 异步线程回调: 基类
{
DelegateAdd da;
protected override void myMain() {
da = fun;
IAsyncResult iar = da.BeginInvoke(6, goBack, null);
}
private int fun(int a) {
WriteLine("fun");
return a + 1;
}
private void goBack(IAsyncResult iar) {
var ret = da.EndInvoke(iar);
WriteLine("goBack 结果:"+ ret);
}
}
class 异步线程等待 : 基类
{
DelegateAdd da;
protected override void myMain()
{
da = fun;
IAsyncResult iar = da.BeginInvoke(6, null, null);
var ret = da.EndInvoke(iar);
WriteLine("goBack 结果:" + ret);
}
private int fun(int a)
{
WriteLine("fun");
return a + 1;
}
}
class 异步线轮询 : 基类
{
DelegateAdd da;
protected override void myMain()
{
da = fun;
IAsyncResult iar = da.BeginInvoke(6, null, null);
while (true) {
if (iar.IsCompleted) {
var ret = da.EndInvoke(iar);
WriteLine("goBack 结果:" + ret);
break;
}
WriteLine("等待");
}
}
private int fun(int a)
{
WriteLine("fun");
return a + 1;
}
}
class 任务回调 : 基类
{
TaskAwaiter<int> taw;
protected override void myMain() {
object o;
Task<int> t = new Task<int>(fun,6);
taw = t.GetAwaiter();
taw.OnCompleted(goBack);
t.Start();
}
public int fun(object o) {
WriteLine("fun");
int a = (int)o;
return a + 2;
}
private void goBack() {
WriteLine("goBack 结果:"+taw.GetResult());
}
}
class 任务等待 : 基类
{
async protected override void myMain()
{
object o;
Task<int> t = new Task<int>(fun, 6);
t.Start();
int a = await t;
WriteLine("goBack 结果:"+a);
}
public int fun(object o)
{
WriteLine("fun");
int a = (int)o;
return a + 2;
}
}
class 任务等待2 : 基类
{
protected override void myMain()
{
object o;
Task<int> t = new Task<int>(fun, 6);
t.Start();
t.Wait();
int a = t.Result;
WriteLine("goBack 结果:"+a);
}
public int fun(object o)
{
WriteLine("fun");
int a = (int)o;
return a + 2;
}
}
class 任务轮询 : 基类
{
TaskAwaiter<int> taw;
protected override void myMain()
{
object o;
Task<int> t = new Task<int>(fun, 6);
t.Start();
while (true) {
if (t.IsCompleted) {
int a = t.Result;
WriteLine("goBack 结果:"+a);
break;
}
WriteLine("等待");
}
}
public int fun(object o)
{
WriteLine("fun");
int a = (int)o;
return a + 2;
}
}
}
3.运行结果
3.1异步实验
线程效率发挥实验
异步线程回调:开始---------------------------------------
1:main 开始
1:main 结束
异步线程回调:结束---------------------------------------
异步线程等待:开始---------------------------------------
1:main 开始
3:fun
4:fun
3:goBack 结果:7
1:goBack 结果:7
1:main 结束
异步线程等待:结束---------------------------------------
异步线轮询:开始---------------------------------------
1:main 开始
1:等待
1:等待
1:等待
1:等待
1:等待
1:等待
1:等待
1:等待
1:等待
1:等待
1:等待
1:等待
1:等待
1:等待
1:等待
1:等待
4:fun
1:等待
1:goBack 结果:7
1:main 结束
异步线轮询:结束---------------------------------------
3.2任务实验
线程效率发挥实验
任务回调:开始---------------------------------------
1:任务回调:main 开始
1:任务回调:main 结束
任务回调:结束---------------------------------------
任务等待:开始---------------------------------------
1:任务等待:main 开始
3:任务回调:fun
4:任务等待:fun
3:任务回调:goBack 结果:8
1:任务等待:main 结束
任务等待:结束---------------------------------------
任务等待2:开始---------------------------------------
1:任务等待2:main 开始
4:任务等待:goBack 结果:8
4:任务等待2:fun
1:任务等待2:goBack 结果:8
1:任务等待2:main 结束
任务等待2:结束---------------------------------------
任务轮询:开始---------------------------------------
1:任务轮询:main 开始
1:任务轮询:等待
1:任务轮询:等待
1:任务轮询:等待
1:任务轮询:等待
1:任务轮询:等待
1:任务轮询:等待
1:任务轮询:等待
3:任务轮询:fun
1:任务轮询:等待
1:任务轮询:goBack 结果:8
1:任务轮询:main 结束
任务轮询:结束---------------------------------------