C# 为什么TaskFactory.StartNew方法不是泛型的?
使用.NET 4.0中的TPL启动新的仅副作用任务(即:不返回结果的任务)的idomatic方法是使用以下API:C# 为什么TaskFactory.StartNew方法不是泛型的?,c#,multithreading,parallel-extensions,C#,Multithreading,Parallel Extensions,使用.NET 4.0中的TPL启动新的仅副作用任务(即:不返回结果的任务)的idomatic方法是使用以下API: Task Task.Factory.StartNew(Action<object>, object) Task.Factory.StartNew(操作,对象) 但是为什么这个API的签名不是这样的呢 Task Task.Factory.StartNew<T>(Action<T>, T) Task.Factory.StartNew(A
Task Task.Factory.StartNew(Action<object>, object)
Task.Factory.StartNew(操作,对象)
但是为什么这个API的签名不是这样的呢
Task Task.Factory.StartNew<T>(Action<T>, T)
Task.Factory.StartNew(Action,T)
还是像这样
Task Task.Factory.StartNew<T>(T, Action<T>)
Task.Factory.StartNew(T,Action)
技术原因还是其他原因?好的,现在我已经正确理解了这个问题:)
我相信这是因为这是一场比赛。我同意这看起来有点奇怪。。。但是,如果您使用的是lambda表达式,那么使用带有状态参数的版本(即
Action
而不是Action
)可能更容易,只需事先捕获您感兴趣的值即可。如果单独指定值和函数,则没有帮助:(根据Stephen Toub(MSFT)的一篇文章,他们假设我们将依赖闭包来传递状态数据。关于签名的模糊性,也有一些借口。()
但是,依靠闭包来解决这个问题似乎是一个临时的解决方案,等待一个更好的解决方案。它是有效的,但这不是一个好的长期解决方案。很多时候,简单地指定一个委托方法,因为操作将是最简单的方法,但是这意味着我们必须使用全局VARS,否则我们就被排除在状态Par之外。电流表通过
我喜欢Hugo的一个建议(来自微软论坛的帖子)。Hugo建议引入TaskState类型,这似乎是一个规避泛型歧义问题的聪明方法 将其应用于Task.Factory.StartNew()签名和Task()构造函数,如下所示: public Task<T>( Action<T> function, TaskState<T> state );
public Task<T,TResult>( Func<T,TResult> function, TaskState<T> state );
TaskState解决方案并不完美,但它似乎比依赖类型转换的闭包要好得多。是的,但Task在Task的结果类型(TResult)中是泛型的,但在“初始状态”(即:任务的输入)类型中不是泛型的.那么…当我调用Task.Factory.StartNew时,它会自动从线程池中获取一个线程吗?@Padu:是的,我相信-虽然你可以拥有自己的任务工厂,它使用不同的线程集,但我相信。有趣的是,TPL团队刚刚发布了一个关于4.5改进的报告;在“最佳实践”部分(第11页),他们描述最好是明确地传递状态(通过操作重载),而不是在闭包中捕获变量。现在,关于这个建议,通用重载肯定是可取的。
var myTask = new Task( MyMethod, new TaskState( stateInfo ) );
...
public void MyMethod( StateInfo stateInfo ) { ... }