这篇文章主要为大家详细介绍了C#实现异步的几个常用方式,文中的示例代码讲解详细,具有一定的学习价值,感兴趣的小伙伴可以了解一下
前言
微信群里的一个提问引发的这个问题,C#异步有多少种实现方式?首先想要知道C#异步有多少中实现方式,首先我们要知道.NET提供的执行异步操作的三种模式,然后再去了解C#异步实现的方式。
.NET异步编程模式
.NET 提供了执行异步操作的三种模式:
- 基于任务的异步模式 (TAP) ,该模式使用单一方法表示异步操作的开始和完成。 TAP 是在 .NET Framework 4 中引入的。 这是在 .NET 中进行异步编程的推荐方法。 C# 中的 async 和 await 关键词以及 Visual Basic 中的 Async 和 Await 运算符为 TAP 添加了语言支持。 有关详细信息,请参阅基于任务的异步模式 (TAP)。
- 基于事件的异步模式 (EAP),是提供异步行为的基于事件的旧模型。 这种模式需要后缀为
Async
的方法,以及一个或多个事件、事件处理程序委托类型和EventArg
派生类型。 EAP 是在 .NET Framework 2.0 中引入的。 建议新开发中不再使用这种模式。 有关详细信息,请参阅基于事件的异步模式 (EAP)。 - 异步编程模型 (APM) 模式(也称为 IAsyncResult 模式),这是使用 IAsyncResult 接口提供异步行为的旧模型。 在这种模式下,同步操作需要
Begin
和End
方法(例如,BeginWrite
和EndWrite
以实现异步写入操作)。 不建议新的开发使用此模式。 有关详细信息,请参阅异步编程模型 (APM)。
C#异步有四种实现方式
C# 异步有多种实现方式,可归纳为以下几类:
1、异步方法(Async Method TAP模式)
使用async/await关键字实现异步编程,这是比较常用的一种异步实现方式。例如:
public async Task TestDoSomeAsync()
{
await Task.Delay(1000);
Console.WriteLine("Async method completed.");
}
2、任务并行库(TPL, Task Parallel Library TAP模式)
通过 Task 和 Task<T> 类型实现异步编程,可以利用多核处理器,并发执行多个独立的任务。例如:
public static async void Main(string[] args)
{
await Task.Run(() =>
{
Console.WriteLine("Test Task 1 completed.");
});
await Task.Run(() =>
{
Console.WriteLine("Test Task 2 completed.");
});
// 等待所有任务完成
Task.WaitAll();
}
3、Asynchronous Programming Model(APM模式)
是一种经典的异步编程模式,需要手动创建回调函数,用于处理完成或错误的通知。可以通过 IAsyncResult 设计模式的 Begin 和 End 方法来实现,其中 Begin 方法开始异步操作,而 End 方法在异步操作完成时执行,并返回异步操作的结果。
需要注意的是,APM 模式通过 IAsyncResult 接口来存储异步操作的状态和结果,相对比较复杂,代码量也较大。同时,在使用 APM 模式时,还需要手动处理回调函数和等待异步操作完成等细节工作,使得开发起来相对较为繁琐。
class Program
{
static void Main(string[] args)
{
// 创建异步操作类实例
MyAsyncClass asyncClass = new MyAsyncClass();
// 开始异步操作
IAsyncResult result = asyncClass.BeginDoWork(null, null);
// 主线程执行其他操作
// 等待异步操作完成并获取结果
int res = asyncClass.EndDoWork(result);
// 处理异步操作的结果
Console.WriteLine("Result: " + res);
Console.ReadLine();
}
}
class MyAsyncClass
{
/// <summary>
/// 异步执行的方法
/// </summary>
/// <param name="callback">callback</param>
/// <param name="state">state</param>
/// <returns></returns>
public IAsyncResult BeginDoWork(AsyncCallback callback, object state)
{
// 创建一个新的异步操作对象
MyAsyncResult result = new MyAsyncResult(state);
// 开始异步操作
Thread thread = new Thread(() =>
{
try
{
// 执行一些操作
int res = 1 + 2;
// 设置异步操作的结果
result.Result = res;
// 触发回调函数
callback?.Invoke(result);
}
catch (Exception ex)
{
// 设置异步操作的异常
result.Error = ex;
// 触发回调函数
callback?.Invoke(result);
}
});
thread.Start();
// 返回异步操作对象
return result;
}
/// <summary>
/// 结束异步执行的方法
/// </summary>
/// <param name="result">result</param>
/// <returns></returns>
public int EndDoWork(IAsyncResult result)
{
// 将 IAsyncResult 转换为 MyAsyncResult 类型,并等待异步操作完成
MyAsyncResult myResult = (MyAsyncResult)result;
myResult.AsyncWaitHandle.WaitOne();
// 在异步操作中抛出异常
if (myResult.Error != null)
{
throw myResult.Error;
}
// 返回异步操作的结果
return myResult.Result;
}
}
class MyAsyncResult : IAsyncResult
{
public bool IsCompleted => AsyncWaitHandle.WaitOne(0);
public WaitHandle AsyncWaitHandle { get; } = new ManualResetEvent(false);
public object AsyncState { get; }
public bool CompletedSynchronously => false;
public int Result { get; set; }
/// <summary>
/// 存储异步操作的结果或异常信息
/// </summary>
public Exception Error { get; set; }
/// <summary>
/// 构造函数
/// </summary>
/// <param name="asyncState">asyncState</param>
public MyAsyncResult(object asyncState)
{
AsyncState = asyncState;
}
}
4、Event-based Asynchronous Pattern(EAP模式)
一种已过时的异步编程模式,需要使用事件来实现异步编程。例如:
需要注意的是,EAP 模式通过事件来实现异步编程,相对于 APM 模式更加简洁易懂,同时也避免了手动处理回调函数等细节工作。但是,EAP 模式并不支持 async/await 异步关键字,因此在一些特定的场景下可能不够灵活。
public class MyAsyncClass : Component
{
/// <summary>
/// 声明一个委托类型,用于定义异步操作的方法签名
/// </summary>
/// <param name="arg"></param>
/// <returns></returns>
public delegate int MyAsyncDelegate(int arg);
/// <summary>
/// 声明一个事件,用于通知异步操作的完成
/// </summary>
public event MyAsyncDelegate OperationNameCompleted;
/// <summary>
/// 异步执行方法,接受一个参数 arg
/// </summary>
/// <param name="arg"></param>
public void DoWorkAsync(int arg)
{
// 将异步操作放入线程池中执行
ThreadPool.QueueUserWorkItem(new WaitCallback(DoWork), arg);
}
/// <summary>
/// 真正的异步操作
/// </summary>
/// <param name="obj"></param>
private void DoWork(object obj)
{
int arg = (int)obj;
int res = arg + 1;
// 触发事件,传递异步操作的结果
OperationNameCompleted?.Invoke(res);
}
}
以上就是C#实现异步的常用方式总结的详细内容,更多关于C#异步的资料请关注织梦云其它相关文章!
本文标题为:C#实现异步的常用方式总结
基础教程推荐
- C# 调用WebService的方法 2023-03-09
- C# List实现行转列的通用方案 2022-11-02
- linux – 如何在Debian Jessie中安装dotnet core sdk 2023-09-26
- 一个读写csv文件的C#类 2022-11-06
- C#控制台实现飞行棋小游戏 2023-04-22
- unity实现动态排行榜 2023-04-27
- winform把Office转成PDF文件 2023-06-14
- C#类和结构详解 2023-05-30
- C# windows语音识别与朗读实例 2023-04-27
- ZooKeeper的安装及部署教程 2023-01-22