我有以下代码:
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
}
我似乎无法像上面那样找到启动此任务的方法。
你能帮忙吗?
由于
答案 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;