2009-12-03 62 views
8

的idomatic的方式开始新的副作用,唯一的任务(即:没有返回结果的任务):为什么TaskFactory.StartNew方法不是通用的?

Task Task.Factory.StartNew(Action<object>, object) 

但是为什么没有按”使用TPL在.NET 4.0中使用下列API牛逼这个API的签名看起来像这样

Task Task.Factory.StartNew<T>(Action<T>, T) 

或类似这样的

Task Task.Factory.StartNew<T>(T, Action<T>) 

技术原因还是其他原因?

回答

7

好了,现在我明白了正确的问题:)

我相信这是因为这意味着是一个direct replacement for ThreadPool.QueueUserWorkItem。我同意这似乎有点奇怪......但如果无论如何你使用的是lambda表达式,它可能更容易使用版本取得一个状态参数(即Action而不是Action<object>),只是捕获值你事先感兴趣。如果你指定的值,并单独功能:(

+1

是,但任务处于任务的结果类型(TResult)通用的,但在“初始状态”的类型不是通用的(即:输入要任务)。 – Frank 2009-12-03 14:21:37

+0

所以......当我打电话给Task.Factory.StartNew它是否从线程池中自动获取一个线程? – 2010-03-19 17:24:42

+0

@Padu:是的,我相信是这样 - 虽然你可以有自己的任务的工厂,使用一组不同的线程,我相信。 – 2010-03-19 17:46:13

3

根据岗位由Stephen Toub(MSFT),他们假设我们要依靠关闭传递状态数据并没有什么帮助。有(http://social.msdn.microsoft.com/Forums/en/parallelextensions/thread/1988294c-de41-476a-a104-aa550b7409f5

但是,依靠关闭来解决这个问题似乎是一个临时的黑客,等待一个更好的解决方案。它的工作原理,但它不是一个好的长期解决方案。很多时候,简单地指定一个委托方法的行动将是最简单的方法,但是这意味着我们必须使用全局变量或我们排除状态参数的传递。

我像雨果的提案之一(来自MS论坛发帖)。雨果建议引入一个TaskState类型,这似乎是一个巧妙的方法来规避泛型歧义问题。

将这一对Task.Factory.StartNew()签名和任务()构造函数,例如:

public Task<T>(Action<T> function, TaskState<T> state); 
    public Task<T,TResult>(Func<T,TResult> function, TaskState<T> state); 

ActionState会有很多像可空类 - 就在一个值的简单包装会员。在实践中,使用TaskState可能是这样的:

var myTask = new Task(MyMethod, new TaskState(stateInfo)); 
    ... 

    public void MyMethod(StateInfo stateInfo) { ... } 

的TaskState <>方案并不完美,但它似乎不是依赖型铸造关闭一个更好的解决方案。

+0

+1有趣,谢谢。 – Frank 2011-04-17 13:11:54

+2

滑稽,该TPL团队刚刚发布关于在4.5的改进一个[白皮书(http://blogs.msdn.com/b/pfxteam/archive/2011/11/10/10235962.aspx);的“最佳实践”部分(11页)中,它们描述,最好是在状态通过显式地(经由动作过载),而不是在闭合捕获变量。现在,关于这一建议,一般的超载肯定是需要的。 – Frank 2011-11-24 13:51:14

相关问题