使用Task.Factory.StartNew传递一个方法参数

我有以下代码:

var task = Task.Factory.StartNew(CheckFiles, cancelCheckFile.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default); private void CheckFiles() { //Do stuff } 

我现在想修改CheckFiles来接受整数和一个BlockingCollection引用

 private void CheckFiles(int InputID, BlockingCollection<string> BlockingDataCollection) { //Do stuff } 

我似乎无法find像上面那样开始执行此任务的方法。

你能帮我吗?

谢谢

最好的select可能是使用一个lambdaexpression式来closures要显示的variables。

但是,在这种情况下要小心,特别是如果你在一个循环中调用它。 (我提到这个,因为你的variables是一个“ID”,在这种情况下这是很常见的)。如果closures了错误范围的variables,你可以得到一个错误。 有关详细信息,请参阅Eric Lippert关于此主题的文章 。 这通常需要做一个临时的:

 foreach(int id in myIdsToCheck) { int tempId = id; // Make a temporary here! Task.Factory.StartNew( () => CheckFiles(tempId, theBlockingCollection), cancelCheckFile.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default); } 

另外,如果你的代码和上面一样,你应该小心使用LongRunning提示 – 使用默认的调度程序,这将导致每个任务获得自己的专用线程,而不是使用ThreadPool。 如果您正在创build许多任务,则可能会产生负面影响,因为您无法获得ThreadPool的优势。 它通常是针对单一的,长时间运行的任务(因此它的名字),而不是在集合的项目上执行的东西,等等。

 class Program { static void Main(string[] args) { Task.Factory.StartNew(() => MyMethod("param value")); } private static void MyMethod(string p) { Console.WriteLine(p); } } 

构造第一个参数作为Action一个实例,例如

 var inputID = 123; var col = new BlockingDataCollection(); var task = Task.Factory.StartNew( () => CheckFiles(inputID, col), cancelCheckFile.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default); 

为了传递一个整数,我同意Reed Copsey的答案。 如果将来你要传递更复杂的结构,我个人喜欢把所有的variables作为匿名types传递。 它看起来像这样:

 foreach(int id in myIdsToCheck) { Task.Factory.StartNew( (Object obj) => { var data = (dynamic)obj; CheckFiles(data.id, theBlockingCollection, cancelCheckFile.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default); }, new { id = id }); // Parameter value } 

你可以在我的博客中了解更多