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日

悬赏问题

  • ¥15 微信会员卡等级和折扣规则
  • ¥15 微信公众平台自制会员卡可以通过收款码收款码收款进行自动积分吗
  • ¥15 随身WiFi网络灯亮但是没有网络,如何解决?
  • ¥15 gdf格式的脑电数据如何处理matlab
  • ¥20 重新写的代码替换了之后运行hbuliderx就这样了
  • ¥100 监控抖音用户作品更新可以微信公众号提醒
  • ¥15 UE5 如何可以不渲染HDRIBackdrop背景
  • ¥70 2048小游戏毕设项目
  • ¥20 mysql架构,按照姓名分表
  • ¥15 MATLAB实现区间[a,b]上的Gauss-Legendre积分