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

时间:2011-11-14 20:00:34

标签: c# .net .net-4.0 task-parallel-library

我有以下代码:

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
}

我似乎无法像上面那样找到启动此任务的方法。

你能帮忙吗?

由于

5 个答案:

答案 0 :(得分:99)

最好的选择可能是使用一个lambda表达式来关闭你想要显示的变量。

但是,在这种情况下要小心,特别是如果你在循环中调用它。 (我提到这个,因为你的变量是一个“ID”,这在这种情况下很常见。)如果你在错误的范围内关闭变量,你就会得到一个bug。有关详细信息,请参阅Eric Lippert's post on the subject。这通常需要临时:

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。如果您正在创建许多任务,这可能会产生负面影响,因为您将无法获得ThreadPool的优势。它通常适用于单个长期运行的任务(因此它的名称),而不是用于处理集合项目等的东西。

答案 1 :(得分:19)

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

    private static void MyMethod(string p)
    {
        Console.WriteLine(p);
    }
}

答案 2 :(得分:6)

对于传递单个整数,我同意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
}

您可以在我的blog

中详细了解相关信息

答案 3 :(得分:5)

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

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

答案 4 :(得分:0)

尝试一下

        var arg = new { i = 123, j = 456 };
        var task = new TaskFactory().StartNew(new Func<dynamic, int>((argument) =>
        {
            dynamic x = argument.i * argument.j;
            return x;
        }), arg, CancellationToken.None, TaskCreationOptions.AttachedToParent, TaskScheduler.Default);
        task.Wait();
        var result = task.Result;