C# 手动实现异步模拟async/await

1、大多数小伙伴在写C# 异步的时候 只需要使用async/await 然后编译器把我们完成一系列操作 下面是自己实现一个模拟代码如下

// 手动实现异步模拟async/await编译器生成的类
public class MyReadFileStateMachine
{
    // 状态:0=初始
    private int _state;

    // 保存局部变量
    private string _resultData;

    // 保存等待的任务
    private Task<string> _ioTask;

    // 模拟启动
    public void Start()
    {
        _state = 0;
        MoveNext();
    }
    public void MoveNext()
    {
        switch (_state)
        {
            case 0:
                Console.WriteLine("【状态0】准备发起IO读取文件");
                // 模拟耗时操作
                _ioTask = SimulateFileReadAsync();

                if (_ioTask.IsCompleted)
                {
                    // 如果已经直接完成,直接往下走
                    _resultData = _ioTask.Result;
                    _state = 2;
                    MoveNext();
                }
                else
                {
                    // 耗时操作还没完成,注册回调。当前函数直接返回
                    _state = 1;
                    var awaiter = _ioTask.GetAwaiter();
                    awaiter.OnCompleted(MoveNext);
                    Console.WriteLine("【状态1】IO等待中,函数退出,线程释放,可以处理别的任务");
                    return;
                }
                break;

            case 1:
                // 耗时操作回来执行代码
                Console.WriteLine("【状态1回调】IO操作完成");
                _resultData = _ioTask.Result;
                _state = 2;
                MoveNext();
                break;

            case 2:
                // await之后的业务代码
                Console.WriteLine($"【状态2】拿到文件内容:{_resultData}");
                Console.WriteLine("全部流程结束");
                break;
        }
    }
    private Task<string> SimulateFileReadAsync()
    {
        return Task.Run(() =>
        {
            // 模拟耗时操作
            Task.Delay(10000).Wait();
            return "这是读取到的文件文本内容";
        });
    }
}

然后这样调用

var sm = new MyReadFileStateMachine();
sm.Start();

其实最底层本质还是通过 Dispatcher

在补充一点如果是操作 文件 网络 IOCP就需要调用WIN32函数就比较复杂了 但是.net平台已经把我们实现好了 

 

posted @ 2026-09-10 11:35  ¥东方不败  阅读(4)  评论(0)    收藏  举报