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

Jon*_*Jon 59 .net c# .net-4.0 task-parallel-library

我有以下代码:

var task = Task.Factory.StartNew(CheckFiles, cancelCheckFile.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default);

private void CheckFiles()
{
  //Do stuff
}
Run Code Online (Sandbox Code Playgroud)

我现在想修改CheckFiles以接受整数和BlockingCollection引用

private void CheckFiles(int InputID, BlockingCollection<string> BlockingDataCollection)
{
  //Do stuff
}
Run Code Online (Sandbox Code Playgroud)

我似乎找不到像上面那样开始这项任务的方法.

你能帮我吗?

谢谢

Ree*_*sey 100

最好的选择可能是使用lambda表达式来关闭要显示的变量.

但是,在这种情况下要小心,特别是如果你在循环中调用它.(我提到这个,因为你的变量是一个"ID",这在这种情况下很常见.)如果你在错误的范围内关闭变量,你就会得到一个bug.有关详细信息,请参阅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);
}
Run Code Online (Sandbox Code Playgroud)

此外,如果你的代码与上面的代码类似,你应该小心使用LongRunning提示 - 使用默认调度程序,这会导致每个任务获得自己的专用线程而不是使用ThreadPool.如果您正在创建许多任务,这可能会产生负面影响,因为您将无法获得ThreadPool的优势.它通常适用于单个长期运行的任务(因此它的名称),而不是用于处理集合项目的任何东西,等等.


Fer*_*ali 20

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

    private static void MyMethod(string p)
    {
        Console.WriteLine(p);
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 7

为了传递一个整数,我同意Reed Copsey的回答.如果您将来要传递更复杂的构造,我个人希望将所有变量作为匿名类型传递.它看起来像这样:

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
}
Run Code Online (Sandbox Code Playgroud)

您可以在我的博客中了解更多相关信息


Ada*_*lph 5

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

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