跳到主要内容

C# 回调与异步模式

介绍

在C#编程中,回调异步模式是处理耗时操作(如文件读写、网络请求等)的常用技术。回调允许我们在某个操作完成后执行特定的代码,而异步模式则允许我们在等待操作完成的同时继续执行其他任务,从而提高程序的响应性和性能。

本文将逐步介绍C#中的回调机制和异步模式,并通过实际案例展示它们的应用场景。

回调机制

什么是回调?

回调是一种编程模式,它允许我们将一个方法(通常是委托)作为参数传递给另一个方法,以便在某个操作完成后调用。回调常用于处理异步操作的结果。

使用委托实现回调

在C#中,委托是实现回调的核心机制。以下是一个简单的回调示例:

csharp
using System;

class Program
{
// 定义一个委托类型
delegate void CallbackDelegate(string message);

static void Main(string[] args)
{
// 创建一个委托实例并指向回调方法
CallbackDelegate callback = new CallbackDelegate(DisplayMessage);

// 调用一个方法并传递回调
PerformOperation(callback);
}

// 回调方法
static void DisplayMessage(string message)
{
Console.WriteLine("Callback received: " + message);
}

// 执行操作并调用回调
static void PerformOperation(CallbackDelegate callback)
{
Console.WriteLine("Performing operation...");
// 模拟耗时操作
System.Threading.Thread.Sleep(2000);
// 调用回调
callback("Operation complete!");
}
}

输出:

Performing operation...
Callback received: Operation complete!

在这个示例中,PerformOperation 方法执行了一个模拟的耗时操作,并在操作完成后调用传递进来的回调方法 DisplayMessage

使用Lambda表达式简化回调

Lambda表达式可以简化回调的编写,使代码更加简洁:

csharp
using System;

class Program
{
delegate void CallbackDelegate(string message);

static void Main(string[] args)
{
// 使用Lambda表达式定义回调
PerformOperation(message => Console.WriteLine("Callback received: " + message));
}

static void PerformOperation(CallbackDelegate callback)
{
Console.WriteLine("Performing operation...");
System.Threading.Thread.Sleep(2000);
callback("Operation complete!");
}
}

输出:

Performing operation...
Callback received: Operation complete!

异步模式

什么是异步模式?

异步模式允许我们在等待某个操作完成的同时继续执行其他任务,从而提高程序的响应性。在C#中,异步模式通常通过 asyncawait 关键字来实现。

使用 asyncawait 实现异步操作

以下是一个简单的异步操作示例:

csharp
using System;
using System.Threading.Tasks;

class Program
{
static async Task Main(string[] args)
{
Console.WriteLine("Starting operation...");
await PerformOperationAsync();
Console.WriteLine("Operation completed.");
}

static async Task PerformOperationAsync()
{
Console.WriteLine("Performing operation...");
// 模拟耗时操作
await Task.Delay(2000);
Console.WriteLine("Operation complete!");
}
}

输出:

Starting operation...
Performing operation...
Operation complete!
Operation completed.

在这个示例中,PerformOperationAsync 方法使用 await 关键字来等待一个模拟的耗时操作完成,而 Main 方法则继续执行其他任务。

结合回调与异步模式

我们可以将回调与异步模式结合使用,以便在异步操作完成后执行特定的代码。以下是一个示例:

csharp
using System;
using System.Threading.Tasks;

class Program
{
delegate void CallbackDelegate(string message);

static async Task Main(string[] args)
{
// 使用Lambda表达式定义回调
await PerformOperationAsync(message => Console.WriteLine("Callback received: " + message));
}

static async Task PerformOperationAsync(CallbackDelegate callback)
{
Console.WriteLine("Performing operation...");
// 模拟耗时操作
await Task.Delay(2000);
// 调用回调
callback("Operation complete!");
}
}

输出:

Performing operation...
Callback received: Operation complete!

实际应用场景

文件读取

在实际应用中,回调与异步模式常用于文件读取操作。以下是一个读取文件内容并调用回调的示例:

csharp
using System;
using System.IO;
using System.Threading.Tasks;

class Program
{
delegate void CallbackDelegate(string content);

static async Task Main(string[] args)
{
string filePath = "example.txt";
await ReadFileAsync(filePath, content => Console.WriteLine("File content: " + content));
}

static async Task ReadFileAsync(string filePath, CallbackDelegate callback)
{
Console.WriteLine("Reading file...");
string content = await File.ReadAllTextAsync(filePath);
callback(content);
}
}

输出:

Reading file...
File content: [文件内容]

网络请求

另一个常见的应用场景是网络请求。以下是一个使用 HttpClient 进行异步网络请求并调用回调的示例:

csharp
using System;
using System.Net.Http;
using System.Threading.Tasks;

class Program
{
delegate void CallbackDelegate(string response);

static async Task Main(string[] args)
{
string url = "https://api.example.com/data";
await FetchDataAsync(url, response => Console.WriteLine("Response: " + response));
}

static async Task FetchDataAsync(string url, CallbackDelegate callback)
{
Console.WriteLine("Fetching data...");
using (HttpClient client = new HttpClient())
{
string response = await client.GetStringAsync(url);
callback(response);
}
}
}

输出:

Fetching data...
Response: [API返回的数据]

总结

通过本文,我们学习了C#中的回调机制和异步模式。回调允许我们在某个操作完成后执行特定的代码,而异步模式则允许我们在等待操作完成的同时继续执行其他任务。结合使用这两种技术,可以显著提高程序的响应性和性能。

在实际应用中,回调与异步模式常用于文件读取、网络请求等耗时操作。通过 asyncawait 关键字,我们可以轻松地实现异步编程。

附加资源与练习

  • 练习1:尝试修改文件读取示例,使其在读取文件后计算文件内容的行数,并将结果传递给回调。
  • 练习2:编写一个异步方法,从多个URL中获取数据,并在所有请求完成后调用回调。
提示

想要深入了解C#异步编程,可以参考微软官方文档:Asynchronous programming with async and await.