【问题标题】:Code after await statement doesn't runawait 语句后的代码不运行
【发布时间】:2020-02-17 05:28:56
【问题描述】:

我知道论坛上有很多类似的问题,但我没有找到与我相同的问题。请看我下面的代码。

public class MainViewModel
    {
        public MainViewModel()
        {
            Test();

        }

        async Task<string> Test()
        {
            var v = await TaskCaller();
            return v;
        }

        Task<string> TestTask()
        {
            new Task<string>(() =>
            {
                Thread.Sleep(2000);
                return "TestTask";
            });
            return null;
        }

        Task<string> TaskCaller()
        {
            var task = new Task<string>(() =>
            {
                return TestTask().Result;
            });

            return task;
        }
    }

永远不会到达 return v 语句。我需要 TaskCaller 的结果来做更多的处理。

【问题讨论】:

    标签: c# wpf asynchronous async-await


    【解决方案1】:

    您没有开始任何任务,因此它们不可能完成(它们将永远被Status = TaskStatus.Created 卡住)。由于这些任务无法完成,您的await 将无限期等待。使用Task.Run,它返回hot(已启动)任务,以便在线程池上安排工作,即:

    Task<string> TestTask()
    {
        return Task.Run(() =>
        {
            Thread.Sleep(2000);
            return "TestTask";
        });
    }
    

    或者更好的选择:

    async Task<string> TestTask()
    {
        await Task.Delay(2000).ConfigureAwait(false);
    
        return "TestTask";
    }
    

    请注意,您的TaskCaller 实际上返回一个空的Task。这显然是一个错误。

    另外:不要通过Task.Wait()Task.Result 阻止任务

    【讨论】:

    • Shlenskly ConfigureAwait(false) 会做什么?
    • @Eldho,它使紧跟在await 之后的代码部分在线程池线程上执行。没有它,您的继续(await 之后的所有内容)可能在启动 Task 的同一线程上执行 - 对 UI 应用程序有利,对非 UI 绑定代码不利。
    • 一般规则是:如果您需要在您的第一个await 之后触摸用户界面,不要使用ConfigureAwait(false) - 只需await 您的Task。如果您不需要触摸 UI,请使用它。
    【解决方案2】:

    我对你的代码做了一些修改

     async Task<string> Test()
            {
                try
                {
                    var v = await TaskCaller();
                    return v;
                }
                catch (Exception ee)
                {
                    throw ee;
                }
            }
    
            async Task<string> TestTask()
            {
                string ty = string.Empty;
                Task<Task> task = new Task<Task>(async () =>
                {
                    Thread.Sleep(2000);
                    ty = "TestTask";
                });
    
                task.Start();
                task.Result.Wait();
                return ty;
            }
    
            async Task<string> TaskCaller()
            {
                string ty = string.Empty;
                Task<Task> task = new Task<Task>(async () =>
                {
                    ty = await TestTask();
                });
                task.Start();
                task.Result.Wait();
                return ty;
            }
    

    【讨论】:

      猜你喜欢
      • 2020-06-23
      • 1970-01-01
      • 1970-01-01
      • 2023-02-07
      • 1970-01-01
      • 2016-04-02
      • 2022-09-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多