【问题标题】:is returning an empty static task in TPL a bad practice?在 TPL 中返回一个空的静态任务是一种不好的做法吗?
【发布时间】:2013-03-11 20:48:37
【问题描述】:

在某些情况下,我希望有条件地运行任务。我使用某种扩展方法,如下所示:

public static class MyTaskExtension{
  private static Task theEmptyTask = Task.Factory.StartNew(() => {}); //This is the question

  public static Task ContinueWith(this Task task, Task continuationTask, Func<bool> condition)
  {
    if condition(){
       ... do the work
    }
    return theEmptyTask;
  }
}

我的期望是 theEmptyTask 已经完成,所以基本上如果我不想做任何事情,我只返回这个任务,而不是返回 null 或新的空任务。

我觉得这种方法应该有一些小故障。有人能看到吗?

【问题讨论】:

  • 如果你打算使用这种方法,不要像你一样开始一个虚拟任务,而是使用TaskCompletionSource
  • 或者只是Task.FromResult

标签: c# static task-parallel-library task


【解决方案1】:

在某些情况下返回已经完成的任务是完全可以接受的。这不是特别经常做的事情,但它已经完成了。

仅使用单个静态已完成任务也没有任何问题。没有必要有一大堆完全一样的不同任务,因为一旦它们完成了,如果它们没有结果,重复使用它们并没有错。

请注意,如果你想返回一个已经完成的任务,你可以使用Task.FromResult 来生成一个比你现在正在做的开销更少的任务,因为你不会创建一个空方法,调度它,等待它要开始,然后立即完成。只需返回 Task.FromResult(false) 就会给你一个已经完成的任务。

如果您使用的是 .NET 4.0,您可以轻松地创建自己的 FromResult:

public static Task FromResult<T>(T result)
{
    var tcs = new TaskCompletionSource<T>();
    tcs.SetResult(result);
    return tcs.Task;
}

【讨论】:

    【解决方案2】:

    只要您交还处于已完成状态的任务(使用TaskCompletionSource 执行此操作),我想不出这有什么问题,因为Task 上实际上没有任何设置器允许客户处理您的静态空任务的类。他们可以在您的任务上调用Dispose(),但我认为这不会造成任何伤害(即我认为它不会影响检查任务属性的能力(还没有尝试过--某事值得测试))。

    【讨论】:

    • @svick,感谢您的链接。在这里拉出相关部分We’ve made Tasks usable even after they’ve been disposed. You can now use all of the public members of Task even after its disposal
    • 是的,请记住,这些更改仅存在于 .Net 4.5 上。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-20
    • 2011-06-01
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 2019-01-24
    • 2019-04-19
    相关资源
    最近更新 更多