Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing a method parameter using Task.Factory.StartNew

I have the following code:

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

I now want to amend CheckFiles to accept and integer and a BlockingCollection reference

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

I can't seem to find a way to Start this task as I did above.

Can you help?

Thanks

like image 339
Jon Avatar asked Nov 14 '11 20:11

Jon


1 Answers

The best option is probably to use a lambda expression that closes over the variables you want to display.

However, be careful in this case, especially if you're calling this in a loop. (I mention this since your variable is an "ID", and this is common in this situation.) If you close over the variable in the wrong scope, you can get a bug. For details, see Eric Lippert's post on the subject. This typically requires making a temporary:

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

Also, if your code is like the above, you should be careful with using the LongRunning hint - with the default scheduler, this causes each task to get its own dedicated thread instead of using the ThreadPool. If you're creating many tasks, this is likely to have a negative impact as you won't get the advantages of the ThreadPool. It's typically geared for a single, long running task (hence its name), not something that would be implemented to work on an item of a collection, etc.

like image 74
Reed Copsey Avatar answered Sep 21 '22 13:09

Reed Copsey