【问题标题】:Instance of Task class (Task.Factory.StartNew or TaskCompletionSource)任务类的实例(Task.Factory.StartNew 或 TaskCompletionSource)
【发布时间】:2011-04-15 09:35:36
【问题描述】:

这可能是一个非常基本的问题,但只是我想确保我的想法正确。 今天在挖TPL库,发现Task类的实例有两种创建方式。

我的方式

 Task<int> t1 = Task.Factory.StartNew(() =>
                {
                    //Some code
                    return 100;

                });

方式二

  TaskCompletionSource<int> task = new TaskCompletionSource<int>();
  Task t2 = task.Task;
  task.SetResult(100);

现在,我只是想知道

  1. 这些实例之间有什么区别吗?
  2. 如果是,那是什么?

【问题讨论】:

    标签: c# multithreading task-parallel-library


    【解决方案1】:

    第二个例子没有创建一个“真正的”任务,即没有代理可以做任何事情。

    您主要使用它来向调用者呈现一个任务接口。看看上面的例子 msdn

        TaskCompletionSource<int> tcs1 = new TaskCompletionSource<int>();
        Task<int> t1 = tcs1.Task;
    
        // Start a background task that will complete tcs1.Task
        Task.Factory.StartNew(() =>
        {
            Thread.Sleep(1000);
            tcs1.SetResult(15);
        });
    
        // The attempt to get the result of t1 blocks the current thread until the completion source gets signaled.
        // It should be a wait of ~1000 ms.
        Stopwatch sw = Stopwatch.StartNew();
        int result = t1.Result;
        sw.Stop();
    
        Console.WriteLine("(ElapsedTime={0}): t1.Result={1} (expected 15) ", sw.ElapsedMilliseconds, result);
    

    【讨论】:

    • 添加更多细节,TaskCompletionSource 是一种包装异步操作的方法,否则当前不支持 TaskFactory.FromAsync 之类的操作。 TaskCompletionSource 的一个示例用法是包装基于事件的异步模式实现,例如 WebClient.DownloadStringAsync。有关更多示例,请参阅msdn.microsoft.com/en-us/magazine/ff959203.aspx
    【解决方案2】:

    由于您没有在上述方式 1 中触发任何异步操作,因此消耗线程池中的另一个线程是在浪费时间(如果您不更改默认的 TaskScheduler)。

    但是,在方式 2 中,您正在生成一个已完成的任务,并且您在同一个线程中执行它。 TCS 也可以被视为一个 threadless 任务(可能是错误的描述,但被多个开发人员使用)。

    【讨论】:

    • @PeterRitchie 你读过我写的吗?如果您要运行不需要线程切换但需要返回 Task 对象的代码,那么您只会浪费时间使用Task.Factory.StartNew。停止使用它并使用 TCS。
    • @PeterRitchie 和Task.Factory.StartNew 不是灵丹妙药,也不是异步的!你可以称它为多线程但不是异步的。异步和多线程是不同的。
    • StartNew 被记录为“异步执行的动作委托”。它可能不使用线程是异步的,但它是异步的。
    • 同步核心如何异步?这是不可能的。
    猜你喜欢
    • 2014-03-31
    • 1970-01-01
    • 2015-03-26
    • 1970-01-01
    • 2015-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多