【问题标题】:Where does Task Execution go?任务执行去哪儿了?
【发布时间】:2016-04-06 10:23:52
【问题描述】:

根据以下代码,我的预期是控制台会发出

  • SayTaskHelloCalled
  • 任务执行中
  • SayHelloAfterSleepTask

但是任务没有运行。只有第一行在控制台中发出。请提出原因?

static void Main(string[] args)
    {
        var task2 = SayHelloTask();
        var result = task2.Result;
        Console.WriteLine(result);
    }

 public static Task<string> SayHelloTask()
        {
            Thread.Sleep(2000);
            Console.WriteLine("SayHelloTaskCalled");
            return  new Task<string>(() => {
                Console.WriteLine("Task Executing");
                return "SayHelloAfterSleepTask";
            });

【问题讨论】:

    标签: c# task-parallel-library task


    【解决方案1】:

    使用它的一个构造函数创建一个新的Task 会给你一个“冷任务”。意味着任务尚未开始。由于您从未启动过任务,因此您看不到预期的输出。

    您需要致电Task.Start 来启动它。为了返回一个“热任务”(Started Task),你需要使用Task.Factory.StartNewTask.Run

    以下应该可以工作:

    public static Task<string> SayHelloTask()
    {
        Thread.Sleep(2000);
        Console.WriteLine("SayHelloTaskCalled");
        return  Task.Run(() => {
            Console.WriteLine("Task Executing");
            return "SayHelloAfterSleepTask";
           });
    }
    

    如果您希望您的任务本身是“冷任务”,请修改您的调用代码,如下所示。

    static void Main(string[] args)
    {
        var task2 = SayHelloTask();
        task2.Start();//<--Start a "Cold task"
        var result = task2.Result;
        Console.WriteLine(result);
    }
    

    【讨论】:

    • 谢谢.. 如果我希望从调用代码开始冷任务,需要进行哪些更改.. 假设出于某种原因我希望调用者决定何时启动引擎:)
    • @helloworld 更新了我的答案。希望有帮助。但我建议不要将冷任务用于公共方法。因为几乎每个 .net 框架方法返回的 Task 都是 Hot Task。返回冷任务会造成不必要的混乱。
    • 哦.. 它有一个 Start().. 非常简洁:) 非常感谢.. 只是一个额外的查询.. 返回 Task v/s async Task 有什么具体区别 .. 因为 Task 已经是背景了.. 我原来的查询已经回答了.. 谢谢
    • 我回答了here。简而言之,一个异步任务将生成一个状态机。其他人没有。
    猜你喜欢
    • 1970-01-01
    • 2011-03-03
    • 2014-03-15
    • 2015-07-17
    • 2012-10-30
    • 2013-05-23
    • 1970-01-01
    • 2012-03-13
    • 1970-01-01
    相关资源
    最近更新 更多