2013-03-22 32 views
15

有些情况下,我想要有条件地运行任务。我使用某种形式的扩展方法是这样的:在TPL中返回一个空的静态任务是一个坏习惯?

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将已经完成,所以基本上,如果我不想做任何事情,我刚回到这个任务,而不是空或新空任务。

我有一种感觉,这种方法应该有一些小故障。任何人都可以看到吗?

+1

如果你打算使用这种方法,像你这样的,而使用'不启动一个虚工TaskCompletionSource'。 – 2013-03-22 13:09:56

+2

或者只是Task.FromResult – 2013-03-22 20:45:17

回答

21

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

只使用一个静态完成的任务也没有任何问题。没有必要完成大量不同的任务,这些任务完全相同,因为一旦它们完成,并且如果它们没有结果,重用它们就没有任何问题。

请注意,如果您想要返回已完成的任务,则可以使用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; 
} 
1

只要你交回一个处于完成状态的任务(使用TaskCompletionSource来做到这一点),我想不出任何问题,因为Task类没有真正的setter,允许客户端使用静态空任务。他们可以在你的任务中调用Dispose(),但我认为这不会造成任何伤害(即我认为这不会影响检查任务属性的能力(还没有尝试过 - 值得测试的东西出))。

+0

@downvoter,小心点评? – 2013-03-22 13:40:38

+1

Stephen Toub有一篇文章解决了'Task.Dispose()'问题](http://blogs.msdn.com/b/pfxteam/archive/2012/03/25/10287435.aspx)。 – svick 2013-03-22 18:52:38

+0

@svick,感谢您的链接。在这里拉出一个相关的部分'我们已经让Tasks在处置后仍然可用。您现在可以使用任务的所有公共成员,即使在处置后。 – 2013-03-22 19:05:58

相关问题