01.异步任务

class Program
{

static void Main(string[] args)
{
Simple simple=new Simple();
simple.DoRun();
Console.WriteLine("main");
Console.ReadKey();
}



class Simple
{
Stopwatch sw=new Stopwatch();

public void DoRun()
{
Console.WriteLine("Caller: Before call");
ShowDealyAsync();
Console.WriteLine("Caller: After call");
}

private async void ShowDealyAsync()
{
sw.Start();
Console.WriteLine(" Before Delay: {0}", sw.ElapsedMilliseconds);
await Task.Delay(3000); //异步延时
Console.WriteLine("延时触发");
Console.WriteLine(" After Delay : {0}", sw.ElapsedMilliseconds);//后续部分
}

}

}



class Program
{
static void Main(string[] args)
{
AsyncTaskOne();
for (int i = 0; i < 10; i++)
{
// Console.WriteLine(Thread.CurrentThread.ManagedThreadId.ToString()); //当前线程的ID
Thread.Sleep(500);
Console.WriteLine($"main:+{i}");
}
Console.ReadKey();
}

private async static void AsyncTaskOne()
{
await Task.Run(() =>
{
// Console.WriteLine(Thread.CurrentThread.ManagedThreadId.ToString());
for (int i = 0; i < 10; i++)
{
Thread.Sleep(500);
Console.WriteLine($"{Thread.CurrentThread.Name}:+{i}");
Console.WriteLine();
}
});
}

}

1.异步_回调函数


03.开启一个任务的三种方式

static void Main(string[] args)
{
AsyncTask();
Console.ReadKey();
}

/// <summary>
/// 开启一个任务的三种方式
/// </summary>
private static void AsyncTask()
{
//1.new方式实例化一个Task,需要通过Start方法启动
Task task1=new Task(() =>
{
Thread.Sleep(500);
Console.WriteLine($"task1的线程ID为{Thread.CurrentThread.ManagedThreadId}");
});
task1.Start();
//2.Task.Factory.StartNew(Action action)创建和启动一个Task
Task task2 = Task.Factory.StartNew(() =>
{
Thread.Sleep(800);
Console.WriteLine($"task2的线程ID为{Thread.CurrentThread.ManagedThreadId}");
});
//3.Task.Run(Action action)将任务放在线程池队列,返回并启动一个Task
Task task3=Task.Run(() =>
{
Thread.Sleep(1000);
Console.WriteLine($"task3的线程ID为{Thread.CurrentThread.ManagedThreadId}");
});
Console.WriteLine("Main");
}

1.异步_回调函数_02


04.创建有返回值的Task

task.Resut获取结果时会阻塞线程,即如果task没有执行完成,会等待task执行完成获取到Result,然后再执行后边的代码,

/// <summary>
/// 带有返回值
/// </summary>
private static void AsyncTaskTwo()
{
Task<string> task1 = new Task<string>(() => $"task1的线程ID是{Thread.CurrentThread.ManagedThreadId}");
task1.Start();
Task<string> task2=Task.Factory.StartNew(() => { return $"task2的线程ID是{Thread.CurrentThread.ManagedThreadId}"; },TaskCreationOptions.LongRunning);
Task<string> task3 = Task<string>.Run(() =>
{
return $"task1的线程ID是{Thread.CurrentThread.ManagedThreadId}";
});
Console.WriteLine("主线程");
Console.WriteLine("task1结果:" + task1.Result);
Console.WriteLine("task2结果:" + task2.Result);
Console.WriteLine("task3结果:" + task3.Result);
}

1.异步_主线程_03


05。同步执行

static void Main(string[] args)
{
AsyncTaskThree();
Console.WriteLine("主线程ID:"+ Thread.CurrentThread.ManagedThreadId);
Console.ReadKey();
}


//task.RunSynchronously() 用于同步执行Task任务

private static void AsyncTaskThree()
{
Task task=new Task(() =>
{
Thread.Sleep(500);
Console.WriteLine("执行Task结束!");
});
//同步执行,task会阻塞主线程
task.RunSynchronously();

}

1.异步_主线程_04


06.

Task的Wait/WaitAny/WaitAll

task.Wait() 表示等待task执行完毕,功能类似于thead.Join(); Task.WaitAll(Task[] tasks) 表示只有所有的task都执行完成了再解除阻塞; Task.WaitAny(Task[] tasks) 表示只要有一个task执行完毕就解除阻塞

static void Main(string[] args)
{
ThreadblockTwo();
Console.WriteLine("主线程执行完毕!");
Console.WriteLine("主线程ID:"+ Thread.CurrentThread.ManagedThreadId);
Console.ReadKey();
}
private static void ThreadblockTwo()
{
Task task1=new Task(() =>
{
Thread.Sleep(2000);
Console.WriteLine("线程1执行完毕!");
});
task1.Start();
Task task2 = new Task(() =>
{
Thread.Sleep(3000);
Console.WriteLine("线程2执行完毕!");
});
task2.Start();
//阻塞主线程。task1,task2都执行完毕再执行主线程
//task1.Wait(); task2.Wait(); //可以实现相同的功能
Task.WaitAll(new Task[]{task1,task2});
//Task.WaitAny(); //task 执行完毕就会解除线程阻塞

}

1.异步_sed_05


07.

所有task执行完毕(或者任一task执行完毕)后,开始执行后续操作

task.WhenAll(Task[] tasks) 表示所有的task都执行完毕后再去执行后续的操作, task.WhenAny(Task[] tasks) 表示任一task执行完毕后就开始执行后续操作

static void Main(string[] args)
{
ThreadblockThree();
Console.WriteLine("主线程执行完毕!");
Console.WriteLine("主线程ID:"+ Thread.CurrentThread.ManagedThreadId);
Console.ReadKey();
}


private static void ThreadblockThree()
{
Task task1 = new Task(() =>
{
Thread.Sleep(500);
Console.WriteLine("线程1执行完毕!");
});
task1.Start();
Task task2 = new Task(() =>
{
Thread.Sleep(1000);
Console.WriteLine("线程2执行完毕!");
});
task2.Start();
//task1,task2执行完了后执行后续操作
Task.WhenAll(task1, task2).ContinueWith((Task t) =>
{
Thread.Sleep(100);
Console.WriteLine("执行后续操作完毕!");
});
//等同于
//Task.Factory.ContinueWhenAll(new Task[] { task1, task2 }, (Task[] t) =>
// {
// Thread.Sleep(100);
// Console.WriteLine("执行后续操作");
//});

}

1.异步_回调函数_06


08.

Task的任务取消(CancellationTokenSource)

private static void CancelTask()
{
CancellationTokenSource source=new CancellationTokenSource();
int index = 0;
Thread thread1=new Thread(() =>
{
while (source.IsCancellationRequested==false )
{
Thread.Sleep(500);
Console.WriteLine($"第{++index}次执行");
}
});
thread1.Start();
//source.CancelAfter(5000) 实现5秒后自动取消任务
//source.CancelAfter(3000);
Thread.Sleep(3000);
// source.Cancel()方法请求取消任务,IsCancellationRequested会变成true
//设置一个状态,设置该对象一个熟悉为true而已,也就是设置cts.IsCancellationRequested为ture。
//所以他根本没有真正的去取消线程的执行,只是设置一个状态而已。
source.Cancel();
Console.WriteLine(source.IsCancellationRequested);

}

1.异步_sed_07


09.source.Token.Register(Action action) 注册取消任务触发的回调函数,即任务被取消时注册的action会被执行

// source.Token.Register(Action action) 注册取消任务触发的回调函数
// 即任务被取消时注册的action会被执行
private static void CancelTaskTwo()
{
CancellationTokenSource source=new CancellationTokenSource();
//注册任务取消的事件
source.Token.Register(() =>
{
//第5次执行在取消回调后打印,这是因为
//执行取消的时候第5次任务已经通过了while()判断,任务已经执行中了
Console.WriteLine("任务取消后的回调!");
});
int index = 0;

Task task=new Task(() =>
{
while (!source.IsCancellationRequested)
{
Thread.Sleep(1000);
Console.WriteLine($"第{++index}次执行,线程运行中...");
}
});
task.Start();
source.CancelAfter(5000);//延时取消
}

1.异步_回调函数_08


10.

async/await