using System;
using System.Threading;
using System.Threading.Tasks;
using static System.Console;
//异步编程
//1.异步模式
//2.基于事件的异步模式
//3.基于任务的异步模式
namespace ConsoleApp
{
class Program
{
public static void TaskMethod(object o)
{
Log(o?.ToString());
}
private static object s_logLock = new object();
public static void Log(string title)
{
lock (s_logLock)
{
WriteLine(title);
WriteLine($"TaskID:{Task.CurrentId?.ToString() ?? "no task"}, " +
$"thread:{Thread.CurrentThread.ManagedThreadId}");
WriteLine($"is background thread: {Thread.CurrentThread.IsBackground}");
WriteLine();
}
}
static void Main(string[] args)
{
//StartNew和Run会立即启动
//方法1
var tf = new TaskFactory();
Task t1 = tf.StartNew(TaskMethod, "using a task factory");
//方法2
Task t2 = Task.Factory.StartNew(TaskMethod, "factory via task");
//方法3
var t3 = new Task(TaskMethod, "using a task constructor and Start");
t3.Start();
//方法4
Task t4 = Task.Run(() => TaskMethod("using the Run method"));
t1.Wait();
t2.Wait();
t3.Wait();
t4.Wait();
//主线程没有任务ID,也不是线程池中的线程
TaskMethod("main thread");
var t5 = new Task(TaskMethod, "run sync");
//会使用相同的线程作为主调线程
t5.RunSynchronously();
//如果任务的代码长时间运行,就应该使用TaskCreationOptions.LongRunning
//即告诉任务调度器创建一个新的线程,而不使用线程池中的线程
var t6 = new Task(TaskMethod, "long running",
TaskCreationOptions.LongRunning);
t6.Start();
//任务结果 future
//使用泛型Task<TResult>
var t7 = new Task<Tuple<int, int>>(TaskWithResult, Tuple.Create(8, 3));
t7.Start();
WriteLine(t7.Result);
t7.Wait();
WriteLine($"result from task: {t7.Result.Item1} {t7.Result.Item2}");
//连续的任务
//一个要使用前一个任务的结果,如果前一个失败了,这个任务就应该执行一些清理工作
//无论前一个任务是如何结束的,后面的任务都会接着启动
Task t8 = new Task(DoOnFirst);
Task t9 = t8.ContinueWith(DoOnSecond);
Task t10 = t8.ContinueWith(DoOnSecond);
Task t11 = t9.ContinueWith(DoOnSecond);
t8.Start();
//出错时启动
Task t12 = t8.ContinueWith(DoOnSecond, TaskContinuationOptions.OnlyOnFaulted);
Task.WaitAll(t8, t9, t10, t11);
//任务取消
CancelTask();
ReadKey();
}
public static Tuple<int, int> TaskWithResult(object divsion)
{
if (divsion is Tuple<int, int>)
{
Tuple<int, int> div = (Tuple<int, int>)divsion;
int result = div.Item1 / div.Item2;
int reminder = div.Item1 % div.Item2;
WriteLine("task creates a result...");
return Tuple.Create(result, reminder);
}
return null;
}
private static void DoOnFirst()
{
WriteLine($"doing some task {Task.CurrentId}");
Task.Delay(1000).Wait();
}
private static void DoOnSecond(Task t)
{
WriteLine($"task {t.Id} finished");
WriteLine($"this task id {Task.CurrentId}");
WriteLine("do some cleanup");
Task.Delay(1000).Wait();
}
public static void CancelTask()
{
var cts = new CancellationTokenSource();
//注册一个将在取消此CancellationToken时调用的委托。
cts.Token.Register(() => WriteLine("*** task canceled"));
//在指定的毫秒数后计划对此CancellationTokenSource 的取消操作。
cts.CancelAfter(500);
//cts.Cancel();//立即取消
Task t1 = Task.Run(() =>
{
WriteLine("in task");
while (true)
{
Task.Delay(100).Wait();
CancellationToken token = cts.Token;
if (token.IsCancellationRequested)
{
WriteLine("canceling was requested, " +
"canceling from within the task");
token.ThrowIfCancellationRequested();
break;
}
WriteLine("in loop");
Task.Yield();
}
WriteLine("task finished without cancellation");
}, cts.Token);
try
{
t1.Wait();
}
catch(AggregateException ex)
{
WriteLine($"exception: {ex.GetType().Name}, {ex.Message}");
foreach(var innerException in ex.InnerExceptions)
{
WriteLine($"inner exception: {ex.InnerException.GetType()}," +
$"{ex.InnerException.Message}");
}
}
}
}
}