Article directory
Preface
Task is an encapsulation of Thread. It is an extremely optimized design, which makes it more convenient for us to control threads.
Task
Task declaration looks like:
public static Task Sleep()
{
}
Task is a type
return value
Directly declaring Task requires a return value.
Return without parameters
public static Task Sleep(int second)
{
return Task.CompletedTask;
}
Return with parameters
public static Task<T> Sleep()
{
return Task.FromResult(T);
}
//举例,返回参数只能唯一,除非使用元祖
public static Task<string> Sleep()
{
return Task.FromResult("Hello world!");
}
Use Task.Result to get the return value
var res = Sleep().Result;
async and await
async and await are controls for asynchronous events, making it easier for us to control asynchronous events.
return value
You can set the return value directly after using async
///有参返回
public static async Task<string> Sleep()
{
return "Hello world";
}
///无参返回
public static async Task Sleep()
{
}
Use with await
Waiting for asynchronous events uses the await method
public static async Task Sleep(int second)
{
await Task.Delay(second * 1000);
Console.WriteLine($"等待{
second}s");
}
static void Main(string[] args)
{
Sleep(3);
Sleep(2);
Sleep(1);
Console.WriteLine("运行完毕");
//使用键盘键入事件阻塞主进程,主进程结束程序会立即退出
Console.ReadKey();
}
Print the result:
The print result shows:
- The synchronization event ends first
- Asynchronous events do not block each other, 3, 2, 1 start at the same time, wait for 3, 2, 1s to print 1, 2, 3.
Main async transformation
The main program is Void and cannot wait.
Change Void to Task to wait for asynchronous events.
Print the result service expectations and wait for the asynchronous events to end before running.
Task advanced
C#Task Cancel Task Execution CancellationTokenSource
C# Task Pause and Cancel
Task thread canceled
Thread used to have the Abort() method to forcibly destroy the thread, but this method was used for great security issues and has been deprecated.
Threads cannot be destroyed directly, they can only be canceled by throwing an exception.
//声明token
var tokenSource = new CancellationTokenSource();
//注册异常抛出
tokenSource.Token.ThrowIfCancellationRequested();
//注册取消事件回调
tokenSource.Token.Register(() =>
{
Console.WriteLine("线程已被取消");
});
。。。。。。别的地方的代码
//取消token,那么之前写ThrowIfCancellationRequested的地方会直接结束
tokenSource.Cancel();
test case
A simple infinite loop function that returns token during runtime and is used to jump out of the program directly.
static async Task Main(string[] args)
{
var token = Loop();
//等待3s抛出异常
await Task.Delay(1000 * 3);
Console.WriteLine("任务完成!");
token.Cancel();
Console.ReadKey();
}
/// <summary>
/// 循环等待
/// </summary>
/// <returns></returns>
public static CancellationTokenSource Loop()
{
var tokenSource = new CancellationTokenSource();
Console.WriteLine("任务开始!");
tokenSource.Token.Register(() =>
{
Console.WriteLine("线程已被取消");
});
var count = 0;
Task.Run(async () =>
{
while (true)
{
await Task.Delay(1000);
//抛出异常,直接结束线程
tokenSource.Token.ThrowIfCancellationRequested();
count++;
Console.WriteLine(count);
}
});
return tokenSource;
}
Print results
It is also safer to use.
Timeout settings
tokenSource.CancelAfter is a timeout method.
CancelAfter(1000): Timeout after 1000 milliseconds
static async Task Main(string[] args)
{
var token = Loop();
///3000毫秒后取消
token.CancelAfter(1000*3);
Console.ReadKey();
}
/// <summary>
/// 循环等待
/// </summary>
/// <returns></returns>
public static CancellationTokenSource Loop()
{
var tokenSource = new CancellationTokenSource();
Console.WriteLine("任务开始!");
tokenSource.Token.Register(() =>
{
Console.WriteLine("线程已被取消");
});
var count = 0;
Task.Run(async () =>
{
while (true)
{
await Task.Delay(1000);
tokenSource.Token.ThrowIfCancellationRequested();
count++;
Console.WriteLine(count);
}
});
return tokenSource;
}
Thread pause and resume
Thread suspension is also controlled using a class, ManualResetEvent. Just like thread destruction, it cannot be paused directly, because it is not safe to pause directly.
//声明,false为默认阻塞,true为不阻塞
var resetEvent = new ManualResetEvent(false);
//暂停,通过WaitOne方法来阻塞线程,通过Set和Reset来设置是否阻塞
resetEvent.WaitOne();
//阻塞暂停
resetEvent.Set()
//取消阻塞,继续
resetEvent.Reset()
test case
static async Task Main(string[] args)
{
var canStop = CanStop();
//等待3s抛出异常
Console.WriteLine("等待3s启动");
await Task.Delay(1000 * 3);
Console.WriteLine("启动!");
canStop.Set();
Console.WriteLine("等待3s暂停");
await Task.Delay(3000);
Console.WriteLine("暂停!");
canStop.Reset();
Console.ReadKey();
}
public static ManualResetEvent CanStop()
{
var resetEvent = new ManualResetEvent(false);
var count = 0;
Task.Run(async () =>
{
while (true)
{
resetEvent.WaitOne();
await Task.Delay(1000);
count++;
Console.WriteLine(count);
}
});
return resetEvent;
}
Multitasking is the fastest
await Task.WhenAny(Task1,Task2,Task3)
will only wait for the fastest one.
static async Task Main(string[] args)
{
await Task.WhenAny(Sleep(1),Sleep(2),Sleep(3));
Console.WriteLine("运行结束");
Console.ReadKey();
}
public async static Task Sleep(int second)
{
await Task.Delay(second*1000);
Console.WriteLine($"等待{
second}s");
}
operation result
Multitasking all waiting
static async Task Main(string[] args)
{
await Task.WhenAll(Sleep(1), Sleep(2), Sleep(3));
Console.WriteLine("运行结束");
Console.ReadKey();
}
public async static Task Sleep(int second)
{
await Task.Delay(second*1000);
Console.WriteLine($"等待{
second}s");
}
in conclusion
The control of asynchronous threads is extremely important. Tasks can also be used together with delegates to have stronger control over the running of the program.