异步编程,await async 和generic host

2020-07-23  本文已影响0人  早睡使人快乐

异步

class Program  
{  
    static void Main(string[] args)  
    {  
        callMethod();  
        Console.ReadKey();  
    }  
  
    public static async void callMethod()  
    {  
        Task<int> task = Method1();  
        Method2();  
        int count = await task;  
        Method3(count);  
    }  
  
    public static async Task<int> Method1()  
    {  
        int count = 0;  
        await Task.Run(() =>  
        {  
            for (int i = 0; i < 100; i++)  
            {  
                Console.WriteLine(" Method 1");  
                count += 1;  
            }  
        });  
        return count;  
    }  
  
    public static void Method2()  
    {  
        for (int i = 0; i < 25; i++)  
        {  
            Console.WriteLine(" Method 2");  
        }  
    }  
  
    public static void Method3(int count)  
    {  
        Console.WriteLine("Total count is " + count);  
    }  
}  

通过await等待method3的执行结果,最后输出


image003.jpg

再来看一个实际的例子

class Program  
{  
    static void Main()  
    {  
        Task task = new Task(CallMethod);  
        task.Start();  
        task.Wait();  
        Console.ReadLine();  
    }  
  
    static async void CallMethod()  
    {  
        string filePath = "E:\\sampleFile.txt";  
        Task<int> task = ReadFile(filePath);  
  
        Console.WriteLine(" Other Work 1");  
        Console.WriteLine(" Other Work 2");  
        Console.WriteLine(" Other Work 3");  
  
        int length = await task;  
        Console.WriteLine(" Total length: " + length);  
  
        Console.WriteLine(" After work 1");  
        Console.WriteLine(" After work 2");  
    }  
  
    static async Task<int> ReadFile(string file)  
    {  
        int length = 0;  
  
        Console.WriteLine(" File reading is stating");  
        using (StreamReader reader = new StreamReader(file))  
        {  
            // Reads all characters from the current position to the end of the stream asynchronously    
            // and returns them as one string.    
            string s = await reader.ReadToEndAsync();  
  
            length = s.Length;  
        }  
        Console.WriteLine(" File reading is completed");  
        return length;  
    }  
}  

主Task会在遇到await后等待Task的执行结果,然后再执行后面的代码,所以得到结果


image004.jpg

再来看Generic host中的异步

    class Program
    {
        static async Task Main(string[] args)
        {
            await CreateHostBuilder(args).Build().RunAsync();
        }

        private static IHostBuilder CreateHostBuilder(string[] args)
        {
            return Host.CreateDefaultBuilder()
            .ConfigureServices((hostContext, services) =>
            {
                services.AddHostedService<Loop250ms>();
                services.AddHostedService<Run5sec>();
            });
        }
    }

在这里注册了Loop250ms和Run5sec两个服务

public class Loop250ms : BackgroundService
    {
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            Console.WriteLine("Loop250ms.ExecuteAsync");
            while(!stoppingToken.IsCancellationRequested)
            {
                Console.WriteLine("(loop)");
                await Task.Delay(250);
            }
            Console.WriteLine("Loop250ms.ExecuteAsync Cancelled");
        }
    }

每250ms输出一次(loop)

public class Run5sec:BackgroundService
    {
        private readonly IHostApplicationLifetime applifetime;
        
        public Run5sec(IHostApplicationLifetime applifetime)
        {
            this.applifetime = applifetime;
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            Console.WriteLine("Tick1000ms.ExecuteAsync");
            for (int i = 5; i > 0;i--)
            {
                if(stoppingToken.IsCancellationRequested) break;
                Console.WriteLine($"tick {i}");
                await Task.Delay(1000);
            }
            Console.WriteLine("Tick1000ms calling StopApplication");
            applifetime.StopApplication();
        }
    }

倒计时5秒,倒计时完成时调用applifetime.StopApplication结束应用
输出结果


image.png

可以看到两个服务互不影响的执行,直到applifetime.StopApplication被调用,应用程序向Loop250ms中传入CancellationToken(的确是这样吗,我也不清楚,求大佬解答)

上一篇下一篇

猜你喜欢

热点阅读