前面了解了进程、线程和任务的相关概念:C#理解进程、线程和任务
下面来了解异步运行任务,为了理解如何同时运行多个任务,将从同步和异步的方式来说明
1.同步执行多个操作
下面创建了三个方法,并在C#中以同步方式操作它们以显示时间:
csharp
using System;
class Program
{
static void Main(string[] args)
{
ShowCurrentTime();
ShowUtcTime();
ShowLocalTime();
}
static void ShowCurrentTime()
{
DateTime currentTime = DateTime.Now;
Console.WriteLine("Current Time: " + currentTime);
}
static void ShowUtcTime()
{
DateTime utcTime = DateTime.UtcNow;
Console.WriteLine("UTC Time: " + utcTime);
}
static void ShowLocalTime()
{
DateTime localTime = DateTime.Now.ToLocalTime();
Console.WriteLine("Local Time: " + localTime);
}
}
在这个示例中,我们定义了三个方法:ShowCurrentTime、ShowUtcTime和ShowLocalTime。然后在Main方法中,以同步方式依次调用这三个方法来显示当前时间、UTC时间和本地时间。
2.使用异步来执行多个操作
当使用异步方式调用这三个方法时,可以使用async和await来等待每个异步操作完成。以下是一个示例,演示了如何在C#中以异步方式调用这三个方法来帮助理解多个任务的异步操作:
csharp
using System;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
Task task1 = ShowCurrentTimeAsync();
Task task2 = ShowUtcTimeAsync();
Task task3 = ShowLocalTimeAsync();
await Task.WhenAll(task1, task2, task3);
}
static async Task ShowCurrentTimeAsync()
{
await Task.Delay(1000); // 模拟耗时操作
DateTime currentTime = DateTime.Now;
Console.WriteLine("Current Time (Async): " + currentTime);
}
static async Task ShowUtcTimeAsync()
{
await Task.Delay(2000); // 模拟耗时操作
DateTime utcTime = DateTime.UtcNow;
Console.WriteLine("UTC Time (Async): " + utcTime);
}
static async Task ShowLocalTimeAsync()
{
await Task.Delay(1500); // 模拟耗时操作
DateTime localTime = DateTime.Now.ToLocalTime();
Console.WriteLine("Local Time (Async): " + localTime);
}
}
在这个示例中,Main方法使用了async关键字,并调用了三个异步方法:ShowCurrentTimeAsync、ShowUtcTimeAsync和ShowLocalTimeAsync。这些异步方法模拟了一些耗时操作,然后使用await关键字来等待它们的完成。最后,使用Task.WhenAll方法来等待所有异步任务完成。
3.等待任务
有时,程序需要等待任务完成后才能继续,在C#中,等待任务完成的常用方法如下:
方法 | 说明 |
---|---|
Task.Wait() | 阻塞当前线程,直到任务完成 |
Task.Result | 获取任务的结果,阻塞当前线程直到任务完成 |
await 关键字 | 非阻塞等待异步任务完成,允许当前线程执行其他操作 |
Task.WaitAll(tasks) | 阻塞当前线程,直到所有任务都完成 |
Task.WhenAll(tasks) | 创建一个新任务,在所有给定任务都完成时完成 |
Task.WaitAny(tasks) | 阻塞当前线程,直到任意一个任务完成 |
Task.WhenAny(tasks) | 创建一个新任务,在任意一个给定任务完成时完成 |
根据需要选择适合的等待任务完成的方法来管理异步操作。
4.继续执行另一项任务
可以使用以下方法来继续执行另一项任务:
Task.ContinueWith 方法:您可以使用Task.ContinueWith方法来指定在当前任务完成后要执行的操作。这样可以创建一个任务链,并在每个任务完成后执行下一个任务。
csharp
Task task1 = Task.Run(() =>
{
// 执行第一个任务
});
task1.ContinueWith((prevTask) =>
{
// 在第一个任务完成后执行的操作
});
async/await:使用async/await关键字可以很方便地实现任务的连续执行。在异步方法中使用await关键字等待前一个异步操作完成后再执行后续操作。
csharp
async Task DoTaskAsync()
{
await Task.Run(() =>
{
// 执行第一个异步任务
});
// 第一个任务完成后执行下一个任务
await Task.Run(() =>
{
// 执行第二个异步任务
});
}
以上是两种常用的方法来继续执行另一项任务。根据具体情况选择适合的方法来管理任务的执行顺序。
5.嵌套任务和子任务
在C#中,嵌套任务和子任务是指一个任务内部创建并执行其他任务的情况。
嵌套任务(Nested Tasks)
嵌套任务是指在一个任务内部创建并执行另一个任务。这样做可以将任务分解为更小的子任务,以便更好地管理和组织代码。
以下是一个简单的示例,演示了如何在一个任务内部创建并执行另一个任务:
csharp
Task outerTask = Task.Run(() =>
{
Console.WriteLine("Outer task started.");
Task innerTask = Task.Run(() =>
{
Console.WriteLine("Inner task started.");
// 执行一些操作
Console.WriteLine("Inner task completed.");
});
// 等待内部任务完成
innerTask.Wait();
Console.WriteLine("Outer task completed.");
});
outerTask.Wait();
在这个示例中,我们首先创建了一个外部任务outerTask,然后在外部任务内部创建了一个嵌套任务innerTask。外部任务等待内部任务完成后才会继续执行。
子任务(Child Tasks)
子任务是指使用Task.Factory.StartNew方法创建的任务,这些任务与父任务并行执行,并不会阻塞父任务的完成。
以下是一个示例,演示了如何创建子任务并行执行:
csharp
Task parentTask = Task.Run(() =>
{
Console.WriteLine("Parent task started.");
Task childTask1 = Task.Factory.StartNew(() =>
{
Console.WriteLine("Child task 1 started.");
// 执行一些操作
Console.WriteLine("Child task 1 completed.");
});
Task childTask2 = Task.Factory.StartNew(() =>
{
Console.WriteLine("Child task 2 started.");
// 执行一些操作
Console.WriteLine("Child task 2 completed.");
});
Task.WaitAll(childTask1, childTask2);
Console.WriteLine("Parent task completed.");
});
parentTask.Wait();
在这个示例中,我们创建了一个父任务parentTask,然后使用Task.Factory.StartNew方法创建了两个子任务childTask1和childTask2。这两个子任务会与父任务并行执行,而父任务会等待所有子任务完成后再继续执行。
希望本文能帮助您更好地理解C#中任务处理的概念和技术。通过同步和异步操作、等待任务完成以及嵌套任务和子任务的示例,您可以更有效地管理任务执行顺序和并行性。如果您有任何疑问或需要进一步的帮助,请随时告诉我。祝您在编程学习和项目开发中取得成功!