C# - 异步执行的四种模式

c++

1个回答

写回答

cx182

2025-06-23 19:45

+ 关注

AI
AI

在C#编程语言中,异步执行是一种非常重要的特性。它使我们能够在应用程序中执行耗时的操作,同时保持应用程序的响应性。C#提供了四种不同的模式来实现异步执行,每种模式都有其独特的优势和用途。

基于委托的异步模式(APM)

基于委托的异步模式(Asynchronous Programming Model,APM)是C#早期引入的异步编程模式。它使用了两个委托来表示异步操作的开始和结束。具体而言,我们使用一个异步的方法来开始操作,并传入一个回调函数来处理操作完成后的结果。

下面是一个简单的例子,展示了如何使用APM模式来执行异步操作:

csharp

public class FileDownloader

{

public void DownloadFile(string url, string destinationPath, Action<bool> callback)

{

WebClient client = new WebClient();

client.DownloadFileCompleted += (sender, e) =>

{

callback(e.Error == null);

};

client.DownloadFileAsync(new Uri(url), destinationPath);

}

}

// 使用示例

FileDownloader downloader = new FileDownloader();

downloader.DownloadFile("http://example.com/file.txt", "C:/Downloads/file.txt", success =>

{

if (success)

{

Console.WriteLine("文件下载成功!");

}

else

{

Console.WriteLine("文件下载失败!");

}

});

在上面的例子中,我们创建了一个FileDownloader类来执行文件下载操作。DownloadFile方法接受一个URL、目标路径和一个回调函数作为参数。回调函数会在文件下载完成后被调用,并传入一个表示下载是否成功的布尔值。

基于事件的异步模式(EAP)

基于事件的异步模式(Event-based Asynchronous Pattern,EAP)是在APM模式的基础上进行了改进和扩展。它引入了两个新的概念:事件和异步操作状态对象。

在EAP模式中,我们使用一个异步方法来开始操作,并通过多个事件来通知操作的进度和结果。同时,我们还可以使用异步操作状态对象来传递额外的信息。

下面是一个使用EAP模式的示例:

csharp

public class FileDownloader

{

public event EventHandler<FileDownloadCompletedEventArgs> FileDownloadCompleted;

public event EventHandler<FileDownloadProgressChangedEventArgs> FileDownloadProgressChanged;

public void DownloadFile(string url, string destinationPath)

{

WebClient client = new WebClient();

client.DownloadFileCompleted += (sender, e) =>

{

FileDownloadCompleted?.Invoke(this, new FileDownloadCompletedEventArgs(e.Error));

};

client.DownloadProgressChanged += (sender, e) =>

{

FileDownloadProgressChanged?.Invoke(this, new FileDownloadProgressChangedEventArgs(e.ProgressPercentage));

};

client.DownloadFileAsync(new Uri(url), destinationPath);

}

}

public class FileDownloadCompletedEventArgs : EventArgs

{

public Exception Error { get; }

public FileDownloadCompletedEventArgs(Exception error)

{

Error = error;

}

}

public class FileDownloadProgressChangedEventArgs : EventArgs

{

public int ProgressPercentage { get; }

public FileDownloadProgressChangedEventArgs(int progressPercentage)

{

ProgressPercentage = progressPercentage;

}

}

// 使用示例

FileDownloader downloader = new FileDownloader();

downloader.FileDownloadCompleted += (sender, e) =>

{

if (e.Error == null)

{

Console.WriteLine("文件下载成功!");

}

else

{

Console.WriteLine("文件下载失败!");

}

};

downloader.FileDownloadProgressChanged += (sender, e) =>

{

Console.WriteLine($"下载进度:{e.ProgressPercentage}");

};

downloader.DownloadFile("http://example.com/file.txt", "C:/Downloads/file.txt");

在上面的例子中,我们使用FileDownloader类来执行文件下载操作。DownloadFile方法开始了一个异步操作,并通过FileDownloadCompleted事件和FileDownloadProgressChanged事件来通知操作的完成和进度。我们可以通过订阅这些事件来处理操作的结果和进展。

基于任务的异步模式(TAP)

基于任务的异步模式(Task-based Asynchronous Pattern,TAP)是引入自C# 5.0的新异步编程模式。它通过使用Task和async/awAIt关键字来简化异步编程。

在TAP模式中,我们可以使用async关键字来标记一个方法为异步方法,并使用awAIt关键字来等待一个异步操作的完成。异步方法会返回一个Task对象,我们可以通过这个对象来获取操作的结果。

下面是一个使用TAP模式的示例:

csharp

public class FileDownloader

{

public async Task<bool> DownloadFileAsync(string url, string destinationPath)

{

try

{

WebClient client = new WebClient();

awAIt client.DownloadFileTaskAsync(new Uri(url), destinationPath);

return true;

}

catch

{

return false;

}

}

}

// 使用示例

FileDownloader downloader = new FileDownloader();

bool success = awAIt downloader.DownloadFileAsync("http://example.com/file.txt", "C:/Downloads/file.txt");

if (success)

{

Console.WriteLine("文件下载成功!");

}

else

{

Console.WriteLine("文件下载失败!");

}

在上面的例子中,我们将DownloadFileAsync方法标记为异步方法,并使用awAIt关键字等待文件下载完成。方法返回一个Task对象,我们可以通过这个对象获取文件下载的结果。

基于异步流的异步模式(IAP)

基于异步流的异步模式(Async Streams-based Asynchronous Pattern,IAP)是引入自C# 8.0的最新异步编程模式。它通过使用异步流(IAsyncEnumerable)和awAIt foreach语法来简化异步流的消费。

在IAP模式中,我们可以使用async关键字来标记一个方法为异步方法,并将其返回类型声明为IAsyncEnumerable。我们可以使用awAIt foreach语法来逐个消费异步流中的元素。

下面是一个使用IAP模式的示例:

csharp

public class FileDownloader

{

public async IAsyncEnumerable<string> GetFileNamesAsync()

{

// 模拟从远程服务器获取文件名列表

awAIt Task.Delay(1000);

yield return "file1.txt";

awAIt Task.Delay(1000);

yield return "file2.txt";

awAIt Task.Delay(1000);

yield return "file3.txt";

}

}

// 使用示例

FileDownloader downloader = new FileDownloader();

awAIt foreach (string fileName in downloader.GetFileNamesAsync())

{

Console.WriteLine($"正在下载文件:{fileName}");

}

在上面的例子中,我们将GetFileNamesAsync方法标记为异步方法,并将其返回类型声明为IAsyncEnumerable。在方法中,我们通过使用yield return来逐个返回文件名。在消费异步流时,我们可以使用awAIt foreach语法来逐个获取文件名并进行处理。

C#提供了四种不同的异步执行模式:基于委托的异步模式(APM),基于事件的异步模式(EAP),基于任务的异步模式(TAP)和基于异步流的异步模式(IAP)。每种模式都有其适用的场景和优势。我们可以根据具体的需求来选择合适的模式来实现异步执行。

无论是使用APM模式、EAP模式、TAP模式还是IAP模式,异步执行都能够显著提高应用程序的性能和响应性。所以在编写C#应用程序时,我们应该充分利用异步执行的特性,以提供更好的用户体验。

希望本文对你理解C#中的四种异步执行模式有所帮助,并能够在实际开发中灵活运用。

举报有用(4)分享收藏

Copyright © 2025 IZhiDa.com All Rights Reserved.

知答 版权所有 粤ICP备2023042255号