xtzy89 2023-03-08 15:00 采纳率: 100%
浏览 45
已结题

async\await用法


private void button1_Click(object sender, EventArgs e)
        {
            Task<int> task = Fun3();
            Task task2 = Func1();
            Console.WriteLine("等待前输出");
            await task;
            await task2;
            //Task.WaitAll(task, task2); //这种写法会阻塞主线程,导致死锁
            Console.WriteLine("等待后输出");
            Console.WriteLine(task.Result);
        }

        private static async Task Func1()
        {
            await Task.Run(() =>
            {
                Thread.Sleep(2000);
                Console.WriteLine("2222");
            });
        }

        private static async Task<int> Fun3()
        {
            int ret = 0;
            await Task.Run(() =>
            {

                var result = Task.Run(async () => await Fun4());
                if (result.Result > 0)
                {
                    Console.WriteLine("正确流程");

                }
                else
                {
                    Console.WriteLine("错误流程");
                    ret = 1;
                }
            });
            return ret;
        }

        private static async Task<int> Fun4()
        {
            int ret = 0;
            await Task.Run(() =>
            {
                if (3 > 2)
                    ret = 1;
            });
            return ret;
        }

Fun1和Func3是2个单独的任务,可以异步执行。Fun3执行时需依赖Fun4的结果,才能执行后续。上边的写法看起来功能可以实现,不过感觉写法有点奇怪,之前用的比较少,请熟悉的人帮忙看下。如果写法有问题,需要怎么修改?

  • 写回答

5条回答 默认 最新

  • MarkHan_ 2023-03-08 15:09
    关注

    该回答引用GPTᴼᴾᴱᴺᴬᴵ
    这段代码的使用 async 和 await 是正确的,可以实现异步执行任务的效果。不过有几点需要注意:

    1.Func1 方法的实现没有必要使用 Task.Run,因为 Task.Run 会把代码放到线程池中执行,而 Thread.Sleep 不会占用线程。所以可以直接写成:

    private static async Task Func1()
    {
        await Task.Delay(2000);
        Console.WriteLine("2222");
    }
    
    
    

    2.Fun3 方法中有一个奇怪的写法:

    var result = Task.Run(async () => await Fun4());
    if (result.Result > 0)
    
    
    

    这里使用 Task.Run 创建了一个新的 Task,并等待其执行完毕,这里的 Task 实际上就是 Fun4 方法的返回值。但是这里使用了 result.Result,这意味着要等待这个 Task 执行完毕并且返回结果才能继续执行后面的代码。这种写法有可能会导致死锁,因为在 UI 线程中等待一个需要执行的任务完成时,如果这个任务需要在 UI 线程中执行,那么就会导致死锁。

    所以,正确的写法应该是:

    int result = await Fun4();
    if (result > 0)
    
    
    

    直接使用 await 等待 Fun4 方法的返回值即可,不需要创建额外的 Task。

    3.await 后面的任务有可能会抛出异常,需要使用 try-catch 捕获并处理异常。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(4条)

报告相同问题?

问题事件

  • 系统已结题 3月26日
  • 已采纳回答 3月18日
  • 创建了问题 3月8日

悬赏问题

  • ¥20 iOS绕地区网络检测
  • ¥15 python验证码滑块图像识别
  • ¥15 根据背景及设计要求撰写设计报告
  • ¥15 QT6颜色选择对话框显示不完整
  • ¥20 能提供一下思路或者代码吗
  • ¥15 用twincat控制!
  • ¥15 请问一下这个运行结果是怎么来的
  • ¥15 单通道放大电路的工作原理
  • ¥30 YOLO检测微调结果p为1
  • ¥15 DS18B20内部ADC模数转换器