首先以一个例子开始
我说明一下这个例子。
这是一个演示异步编程的例子。
- 输入job [name],在一个同步的
Main
方法中,以一发即忘
的方式调用异步方法StartJob()
。 - 输入time,调用同步方法
PrintCurrentTime()
输出时间。 - 输出都带上线程ID,便于观察。
可以看到,主线程不会阻塞。主线程在同步方法中使用一发即忘
的方式调用异步方法时,在异步方法中碰到阻塞时,主线程返回同步方法中继续执行。而异步方法在另一个线程中继续执行。
程序如下
internal class Program
{
static void Main(string[] args)
{
while (true)
{
Console.WriteLine($"(Thread ID: {Thread.CurrentThread.ManagedThreadId}) Enter 'time' to get current time or 'job [name]' to start a job:");
string input = Console.ReadLine();
if (input.StartsWith("time"))
{
// 输出当前时间
PrintCurrentTime();
}
else if (input.StartsWith("job"))
{
// 启动一个异步任务,执行指定的工作
string[] parts = input.Split(new char[] { ' ' }, 2);
string jobName = parts.Length > 1 ? parts[1] : string.Empty;
StartJob(jobName);
}
else
{
Console.WriteLine("Invalid input. Please try again.");
}
}
}
static void PrintCurrentTime()
{
Console.WriteLine($"(Thread ID: {Thread.CurrentThread.ManagedThreadId}) Current time: {DateTime.Now}");
}
static async void StartJob(string jobName)
{
// 获取主线程的线程 ID
int mainThreadId = Thread.CurrentThread.ManagedThreadId;
// 检查是否在主线程上
bool onMainThread = Thread.CurrentThread.ManagedThreadId == mainThreadId;
Console.WriteLine($"(Thread ID: {Thread.CurrentThread.ManagedThreadId}) Starting job '{jobName}'. This will take 10 seconds...");
// 输出主线程上下文