gpt4 book ai didi

多线程合集(三)---异步的那些事之自定义AsyncTaskMethodBuilder

转载 作者:我是一只小鸟 更新时间:2023-05-25 14:31:44 27 4
gpt4 key购买 nike

引言    

    之前在上一篇文章中 多线程合集(二)---异步的那些事,async和await原理抛析 ,我们从源码去分析了async和await如何运行,以及将编译后的IL代码写成了c#代码,以及实现自定义的Awaiter,自定义异步状态机同时将本系列的第一篇文章的自定义TaskScheduler和自定义的Awaiter结合起来,将代码跑了起来,而在c#10之后,我们可以实现自定义的异步生成器,在上一篇文章中,我们将编译后的代码还原成了c#代码,其中就有用到了一个AsyncTaskMethodBuilder的类,搁以前我们只能使用编译器编译之后的AsyncTaskMethodBuilder,现在我们已经可以自定义了,如果再加上上一章节的自定义状态机,加调度,可能会更好玩一些,接下来就为大家奉上代码.

代码

   总共没有多少代码,只是为了简单的实现自定义的AsyncTaskMethodBuilder, 当然可能后续某位哥哥会用到将这些知识点串联起来使用呢,可以看到,下面我们继承了Task,实现了MyTask,此处演示效果,仅仅实现了一个构造函数以及一个GetAwaiter的方法,然后上面就是我们测试调用的Test方法,为什么还需要new一个新的GetAwaiter呢,如果我们使用默认的TaskAwaiter,那你在Main方法await tes.Test的时候就会卡死的至于原因,就是await之后的代码等待结果是等待await之后的返回到上一层也就是说await后面的主动推结果,但是卡死是因为上一层却主动找我要结果导致的卡死,导致我推不过去,上一层也找不到结果,此处我没有具体分析,但是我的猜测是这样,看官们可以自己尝试一下,将MyTask的GetAwaiter注释,使用默认的TaskAwaiter,然后调用Test方法,如果是await的时候肯定卡死,但是如果Task同步运行,也就是RunSynchronously这种方式运行,然后直接.Result,就可以获取到结果,刚好可以验证我上面的猜测,同一上下文了,不需要他主动推,但我可以主动获取, 。

   然后在往下面走就是我们自定义的一个Awaiter,实现接口后,构造函数的Func是我们返回结果的委托,这个结果是GetResult之后的结果值,OnCompleted方法和下面的Unsafe都是去推进状态机告诉已经完了异步的,上一章节说过这两个方法的参数Action,实际上就是状态机的MoveNext方法,最后就到了我们的自定义Builder实现,只需要遵循如下条件,官网列出的条件,既可以实现一个自定义的Builder, 。

                          
                            //
                          
                          
                             See 
                          
                          
                            https://aka.ms/new-console-template
                          
                          
                             for more information
                          
                          
                            using
                          
                          
                             System.Reflection.PortableExecutable;

                          
                          
                            using
                          
                          
                             System.Runtime.CompilerServices;

                          
                          
                            using
                          
                          
                             System.Threading.Tasks;

                          
                          
                            public
                          
                          
                            class
                          
                          
                             Program
{
    
                          
                          
                            static
                          
                          
                            async
                          
                           Task Main(
                          
                            string
                          
                          
                            [] args)
    {

        
                          
                          
                            var
                          
                           tes = 
                          
                            new
                          
                          
                             TestAsync();
        
                          
                          
                            var
                          
                           task =
                          
                            await
                          
                          
                             tes.Test();
        Console.ReadKey();
    }
}

                          
                          
                            public
                          
                          
                            class
                          
                          
                             TestAsync
{
    
                          
                          
                            public
                          
                          
                            async
                          
                           MyTask<
                          
                            int
                          
                          >
                          
                             Test()
    { 
        
                          
                          
                            await
                          
                           MyTask<
                          
                            int
                          
                          >.Delay(
                          
                            1
                          
                          
                            );
        
                          
                          
                            return
                          
                          
                            100
                          
                          
                            ;
    }
}

[AsyncMethodBuilder(
                          
                          
                            typeof
                          
                          (MyTaskBuilder<>
                          
                            ))]

                          
                          
                            public
                          
                          
                            class
                          
                           MyTask<T> : Task<T> 
                          
                            where
                          
                          
                             T : notnull
{
    
                          
                          
                            public
                          
                           MyTask(Func<T> action) : 
                          
                            base
                          
                          
                            (action) 
    {
        Action 
                          
                          =
                          
                             action;
    }

    
                          
                          
                            public
                          
                           Task<T> Task { 
                          
                            get
                          
                          
                            ; }
    
                          
                          
                            public
                          
                           Func<T> Action { 
                          
                            get
                          
                          
                            ; }

    
                          
                          
                            //
                          
                          
                            //
                          
                          
                             摘要:
    
                          
                          
                            //
                          
                          
                                 Gets an awaiter used to await this System.Threading.Tasks.Task`1.
    
                          
                          
                            //
                          
                          
                            //
                          
                          
                             返回结果:
    
                          
                          
                            //
                          
                          
                                 An awaiter instance.
                          
                          
                            public
                          
                          
                            new
                          
                           CustomAwaiter<T>
                          
                             GetAwaiter()
    { 
       
                          
                          
                            var
                          
                           awaiter=
                          
                            new
                          
                           CustomAwaiter<T>
                          
                            (Action);
        
                          
                          
                            return
                          
                          
                             awaiter;
    }

    
                          
                          
                            //
                          
                          
                             添加构造函数和其他功能代码
                          
                          
                            }

                          
                          
                            public
                          
                          
                            class
                          
                           CustomAwaiter<T>
                          
                             : ICriticalNotifyCompletion
{
    
                          
                          
                            public
                          
                           CustomAwaiter(Func<T>
                          
                             func)
    {
        Func 
                          
                          =
                          
                             func;
    }
    
                          
                          
                            public
                          
                          
                            bool
                          
                           IsCompleted { 
                          
                            get
                          
                          ; 
                          
                            set
                          
                          
                            ; }
    
                          
                          
                            public
                          
                           Func<T> Func { 
                          
                            get
                          
                          
                            ; }

    
                          
                          
                            public
                          
                          
                            void
                          
                          
                             OnCompleted(Action continuation)
    {
        continuation();
        IsCompleted 
                          
                          = 
                          
                            true
                          
                          
                            ;
    }

    
                          
                          
                            public
                          
                          
                            void
                          
                          
                             UnsafeOnCompleted(Action continuation)
    {
        continuation();
        IsCompleted 
                          
                          = 
                          
                            true
                          
                          
                            ;
    }
    
                          
                          
                            public
                          
                          
                             T GetResult()
    {
        
                          
                          
                            return
                          
                          
                             Func() ;
    }
}


                          
                          
                            public
                          
                          
                            class
                          
                           MyTaskBuilder<T> 
                          
                            where
                          
                          
                             T:notnull
{
    
                          
                          
                            private
                          
                          
                            readonly
                          
                           AsyncTaskMethodBuilder<T> _builder = 
                          
                            new
                          
                           AsyncTaskMethodBuilder<T>
                          
                            ();
    
                          
                          
                            private
                          
                          
                             T Value;
    
                          
                          
                            public
                          
                          
                            static
                          
                           MyTaskBuilder<T>
                          
                             Create()
    {
        
                          
                          
                            return
                          
                          
                            new
                          
                           MyTaskBuilder<T>
                          
                            ();
    }

    
                          
                          
                            public
                          
                          
                            void
                          
                           Start<TStateMachine>(
                          
                            ref
                          
                           TStateMachine stateMachine) 
                          
                            where
                          
                          
                             TStateMachine : IAsyncStateMachine
    {
        _builder.Start(
                          
                          
                            ref
                          
                          
                             stateMachine);
    }

    
                          
                          
                            public
                          
                          
                            void
                          
                          
                             SetStateMachine(IAsyncStateMachine stateMachine)
    {
        _builder.SetStateMachine(stateMachine);
    }

    
                          
                          
                            public
                          
                          
                            void
                          
                          
                             SetResult(T val)
    {
        Value 
                          
                          =
                          
                             val;
        _builder.SetResult(val);
    }

    
                          
                          
                            public
                          
                          
                            void
                          
                          
                             SetException(Exception exception)
    {
        _builder.SetException(exception);
    }
    
                          
                          
                            public
                          
                           MyTask<T>
                          
                             Task
    {
        
                          
                          
                            get
                          
                          
                            
        {
            
                          
                          
                            return
                          
                          
                            new
                          
                           MyTask<T>(
                          
                            new
                          
                           Func<T>(() =>
                          
                             Value));
        }
    }

    
                          
                          
                            public
                          
                          
                            void
                          
                           AwaitOnCompleted<TAwaiter, TStateMachine>(
                          
                            ref
                          
                           TAwaiter awaiter, 
                          
                            ref
                          
                          
                             TStateMachine stateMachine)
        
                          
                          
                            where
                          
                          
                             TAwaiter : INotifyCompletion
        
                          
                          
                            where
                          
                          
                             TStateMachine : IAsyncStateMachine
    {
        _builder.AwaitOnCompleted(
                          
                          
                            ref
                          
                           awaiter, 
                          
                            ref
                          
                          
                             stateMachine);
    }

    
                          
                          
                            public
                          
                          
                            void
                          
                           AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(
                          
                            ref
                          
                           TAwaiter awaiter, 
                          
                            ref
                          
                          
                             TStateMachine stateMachine)
        
                          
                          
                            where
                          
                          
                             TAwaiter : ICriticalNotifyCompletion
        
                          
                          
                            where
                          
                          
                             TStateMachine : IAsyncStateMachine
    {
        _builder.AwaitUnsafeOnCompleted(
                          
                          
                            ref
                          
                           awaiter, 
                          
                            ref
                          
                          
                             stateMachine);
    }
}

                          
                          
                            public
                          
                          
                            class
                          
                          
                             StateMachine : IAsyncStateMachine
{
    
                          
                          
                            public
                          
                          
                             StateMachine()
    {
        
    }
    
                          
                          
                            public
                          
                          
                            void
                          
                          
                             MoveNext()
    {
        
                          
                          
                            throw
                          
                          
                            new
                          
                          
                             NotImplementedException();
    }

    
                          
                          
                            public
                          
                          
                            void
                          
                          
                             SetStateMachine(IAsyncStateMachine stateMachine)
    {
        
                          
                          
                            throw
                          
                          
                            new
                          
                          
                             NotImplementedException();
    }
}
                          
                        

自定义Builder的条件

    自定义AsyncTaskMethodBuilder,需要满足一下条件,即你定义的这个Builder类需要有Create方法,Task的属性,SetException,设置异常的,SetResult设置结果的,以及一个Start的方法,同时在需要指定异步Builder的类或者方法使用AsyncMethodBuilderArrtibute特性,里面需要的参数就是你自定义Builder的type,即要么在MyTask类上面使用此特性,也可以直接在Test方法上面添加此特性都可以实现自定义Builder,当然了此处有个扩展就是你可以参考上一章节的自定义状态机,调度器,awaiter,自己手动实现编译器编译之后的代码,也就是下面这一段,当然了,内功深厚自己借此实现一个简单的异步也是没问题的,自己实现Task,类似我如上,继承Task,然后借助线程上下文等一些api,去实现一个自己的异步也不是什么难得事情,总之,此片文章实际上可能业务中会用不到,但是结合前几篇,也可以更好的理解async和await了.

                              CustomAsyncStateMechine customAsyncStateMechine = 
                          
                            new
                          
                          
                             CustomAsyncStateMechine();
            customAsyncStateMechine.builder 
                          
                          = AsyncTaskMethodBuilder<
                          
                            string
                          
                          >
                          
                            .Create();
            customAsyncStateMechine.State 
                          
                          = -
                          
                            1
                          
                          
                            ;
            customAsyncStateMechine.builder.Start(
                          
                          
                            ref
                          
                          
                             customAsyncStateMechine);
            
                          
                          
                            return
                          
                           customAsyncStateMechine.builder.Task;
                        

  。

         。

结束

    今天水的一篇博客就到这里了,因为大家能更好的理解async和await,能够将这些自定义的东西玩出花来,哈哈,关于async和await以及线程方面,感兴趣的可以看看我之前的文章.

  。

最后此篇关于多线程合集(三)---异步的那些事之自定义AsyncTaskMethodBuilder的文章就讲到这里了,如果你想了解更多关于多线程合集(三)---异步的那些事之自定义AsyncTaskMethodBuilder的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com