zoukankan      html  css  js  c++  java
  • 构造函数需要异步操作,使用异步初始化模式

    类型的构造函数中含有异步操作,为了完全初始化对象实例成功,又不能使用异步工厂模式,因为这个实例是反射动态创建的(控件库依赖注入/反转,数据绑定,Activator.CreateInstance等)。此时可采用异步初始化模式创建实例,多应用于服务端。

    static void Main(string[] args)
    {
        PrintThreadId("Main begin");
    
        Task.Run(() =>
        {
            PrintThreadId("Thread begin");
            DemoTask2().ConfigureAwait(false);
            PrintThreadId("Thread END");
        });
        PrintThreadId("Main END");
        Console.ReadKey();
    }
    /// <summary>
    /// 异步初始化场景
    /// </summary>
    /// <returns></returns>
    private static async Task DemoTask2()
    {
        PrintThreadId("DemoTask2 begin");
        if (_fundamental == null)
        {
            _fundamental = UltimateDIFactory.Create<MyFundamentalType>();
            var instanceAsyncInit = _fundamental as IAsyncInitialization;
            if (instanceAsyncInit != null)
            {
                await instanceAsyncInit.Initialization;
            }
        }
        _fundamental.Test();
        PrintThreadId("DemoTask2 END");
    }
    
    static IMyFundamentalType _fundamental;
    
    /// <summary>
    /// 当前线程信息
    /// </summary>
    /// <param name="msg"></param>
    static void PrintThreadId(string msg)
    {
        Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss} [{Thread.CurrentThread.ManagedThreadId}]: {msg}");
    }
    

    /// <summary>
    /// 类型定义
    /// </summary>
    class MyFundamentalType : IMyFundamentalType, IAsyncInitialization
    {
        public Task Initialization { get; private set; }
    
        private readonly IMyFundamentalType _otherType;
        private readonly IMyFundamentalType _another;
        private readonly IMyFundamentalType _another2;
    
        public MyFundamentalType(IMyFundamentalType otherType, IMyFundamentalType another, IMyFundamentalType another2)
        {
            _otherType = otherType;
            _another = another;
            _another2 = another2;
            Initialization = InitializeAsync();
        }
        private async Task InitializeAsync()
        {
            PrintThreadId("MyFundamentalType InitializeAsync begin");
            // 异步等待3个实例初始化
            await AsyncInitialization.WhenAllInitializedAsync(_otherType, _another, _another2);
            // 自己的异步初始化过程
            await Task.Delay(TimeSpan.FromSeconds(2));
            PrintThreadId("MyFundamentalType InitializeAsync END");
        }
        /// <summary>
        /// 类型方法
        /// </summary>
        public void Test()
        {
            Console.WriteLine("MyFundamentalType.Test Method");
        }
    }
    
    /// <summary>
    /// 需要DI的类型1
    /// </summary>
    public class MyFundamentalTest : IMyFundamentalType, IAsyncInitialization
    {
        public Task Initialization { get; private set; }
        public MyFundamentalTest()
        {
            Initialization = InitializeAsync();
        }
        private async Task InitializeAsync()
        {
            PrintThreadId("IMyFundamentalType Test1 InitializeAsync begin");
            // 自己的异步初始化过程
            await Task.Delay(TimeSpan.FromSeconds(1));
            PrintThreadId("IMyFundamentalType Test1 InitializeAsync END");
        }
        public void Test() { }
    }
    /// <summary>
    /// 需要DI的类型2
    /// </summary>
    public class MyFundamentalTest2 : IMyFundamentalType, IAsyncInitialization
    {
        public Task Initialization { get; private set; }
        public MyFundamentalTest2()
        {
            Initialization = InitializeAsync();
        }
        private async Task InitializeAsync()
        {
            PrintThreadId("IMyFundamentalType Test2 InitializeAsync begin");
            // 自己的异步初始化过程
            await Task.Delay(TimeSpan.FromSeconds(2));
            PrintThreadId("IMyFundamentalType Test2 InitializeAsync END");
        }
        public void Test() { }
    }
    /// <summary>
    /// 需要DI的类型3
    /// </summary>
    public class MyFundamentalTest3 : IMyFundamentalType, IAsyncInitialization
    {
        public Task Initialization { get; private set; }
        public MyFundamentalTest3()
        {
            Initialization = InitializeAsync();
        }
        private async Task InitializeAsync()
        {
            PrintThreadId("IMyFundamentalType Test3 InitializeAsync begin");
            // 自己的异步初始化过程
            await Task.Delay(TimeSpan.FromSeconds(3));
            PrintThreadId("IMyFundamentalType Test3 InitializeAsync END");
        }
        public void Test() { }
    }
    
    /// <summary>
    /// 为那些需要异步初始化器的对象定义一个标记接口
    /// </summary>
    public interface IAsyncInitialization
    {
        /// <summary>
        /// 初始化器的结果
        /// </summary>
        Task Initialization { get; }
    }
    /// <summary>
    /// 同类型接口
    /// </summary>
    interface IMyFundamentalType
    {
        void Test();
    }
    
    /// <summary>
    /// 异步初始化器辅助类
    /// </summary>
    public static class AsyncInitialization
    {
        /// <summary>
        /// 含有异步初始化器的对象全部完成
        /// </summary>
        /// <param name="instances"></param>
        /// <returns></returns>
        public static Task WhenAllInitializedAsync(params object[] instances)
        {
            return Task.WhenAll(instances.OfType<IAsyncInitialization>().Select(x => x.Initialization));
        }
    }
    /// <summary>
    /// DI工厂
    /// </summary>
    public static class UltimateDIFactory
    {
        public static T Create<T>()
        {
            var test = new Program.MyFundamentalTest();
            var test2 = new Program.MyFundamentalTest2();
            var test3 = new Program.MyFundamentalTest3();
    
            return (T)Activator.CreateInstance(typeof(T), test, test2, test3);
        }
    }   
    
  • 相关阅读:
    Hadoop面试题总结(三)——MapReduce
    Hadoop面试题总结(二)——HDFS
    Hadoop面试题(一)
    html table有跨行跨列时,设置td宽度失效
    ubuntu14.04 安装五笔输入法(fcitx)
    NetCore生产环境禁用Swagger教程
    使用Jenkins与Docker持续集成与发布NetCore项目(实操篇)
    解决 Docker Unable to load the service index for source https://api.nuget.org/v3/index.json 问题
    .net webapi 接收图片保存到服务器,并居中剪裁压缩图片
    .net webapi 接收 xml 格式数据的三种情况
  • 原文地址:https://www.cnblogs.com/wesson2019-blog/p/13611266.html
Copyright © 2011-2022 走看看