C#之async和await

2024-10-28  本文已影响0人  小羊爱学习

一:async

二:await

例子1:


image.png

例子2:


image.png
image.png
可以看到,await只会等待当前方法体内,而不影响方法外部

同时也要注意避免在不需要异步操作的方法中使用async和await,因为它们会增加不必要的开销。

为了更好的理解,我写了一个下载图片的例子,并通过打印来深度理解一下他们的用法:

            Task t = TestTaskPoint();
            Debug.WriteLine($"TestTaskPoint这个任务的状态:{t.Status}");
            // 因为TestTaskPoint里用了await task,所以不会阻塞主线程
            Debug.WriteLine("主线程不会被TestTaskPoint阻塞,继续做别的事情");

            Task.Run(() =>
            {
                Thread.Sleep(7000);// 我们等TestTaskPoint全部执行完后看一下状态
                Debug.WriteLine($"TestTaskPoint这个任务的状态:{t.Status}");
            });
 private async Task TestTaskPoint()
 {
     Debug.WriteLine("TestTaskPoint--{0}", Thread.CurrentThread.ManagedThreadId);
     CancellationTokenSource cts222 = new CancellationTokenSource();
     CancellationToken token333 = cts222.Token;
     Task task = Task.Run(async () =>
     {
         for (int i = 0; i < 10; i++)
         {
             token333.ThrowIfCancellationRequested();
             Console.WriteLine($"任务进行中 {i}---{Thread.CurrentThread.ManagedThreadId}");
             await Task.Delay(1000);// 模拟耗时任务,不阻塞线程方式,比如网络下载图片去了
         }
         Console.WriteLine("任务完成.");
     }, token333);


     // 此处用来模拟用户3秒后点击了停止下载图片任务
     await Task.Delay(3000);// 模拟主线程工作耗时,不阻塞线程方式,不影响主线程取响应UI或等的任务
     cts222.Cancel(); // 某个情况下任务被取消,比如这两行代码放在用户点击全部停止按钮事件里

     try
     {
         await task; // 等待任务完成 或 取消 
     }
     catch (OperationCanceledException ex)
     {
         Debug.WriteLine("捕获到异常---任务被取消:{0}--{1}", ex.Message, Thread.CurrentThread.ManagedThreadId);// 比如提示下载图片中途被中断了
     }
     Debug.WriteLine("任务完成或取消后做一些其他事情:{0}",Thread.CurrentThread.ManagedThreadId);// 比如图片全部下载成功提示

 }

来看一下打印:


image.png

最后整理一下:

        private void TestAsync()
        {
            Task t = TestTaskPoint();
            Debug.WriteLine($"TestTaskPoint这个任务的状态:{t.Status}");
            // 因为TestTaskPoint里用了await task,所以不会阻塞主线程
            Debug.WriteLine("主线程不会被TestTaskPoint阻塞,继续做别的事情");

            Task.Run(() =>
            {
                Thread.Sleep(7000);// 我们等TestTaskPoint全部执行完后看一下状态
                Debug.WriteLine($"TestTaskPoint这个任务的状态:{t.Status}");
            });
        }

        private void TestAsync2()
        {
            _ = TestTaskPoint();// 如果不需要TestTaskPoint这个任务的状态,也可以这样写
            // 因为TestTaskPoint里用了await task,所以不会阻塞主线程
            Debug.WriteLine("主线程不会被TestTaskPoint阻塞,继续做别的事情");
        }

        private async void TestAsync3()
        {
            await TestTaskPoint();
            Debug.WriteLine("主线程被TestTaskPoint阻塞");
        }
上一篇 下一篇

猜你喜欢

热点阅读