Passing a method parameter using Task.Factory.StartNew

前端 未结 5 756
灰色年华
灰色年华 2020-12-08 01:34

I have the following code:

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

priv         


        
相关标签:
5条回答
  • 2020-12-08 02:10

    For passing a single integer I agree with Reed Copsey's answer. If in the future you are going to pass more complicated constucts I personally like to pass all my variables as an Anonymous Type. It will look something like this:

    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
    }
    

    You can learn more about it in my blog

    0 讨论(0)
  • 2020-12-08 02:18

    Try this,

            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;
    
    0 讨论(0)
  • 2020-12-08 02:24

    Construct the first parameter as an instance of Action, e.g.

    var inputID = 123;
    var col = new BlockingDataCollection();
    var task = Task.Factory.StartNew(
        () => CheckFiles(inputID, col),
        cancelCheckFile.Token,
        TaskCreationOptions.LongRunning,
        TaskScheduler.Default);
    
    0 讨论(0)
  • 2020-12-08 02:32

    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.

    0 讨论(0)
  • 2020-12-08 02:33
    class Program
    {
        static void Main(string[] args)
        {
            Task.Factory.StartNew(() => MyMethod("param value"));
        }
    
        private static void MyMethod(string p)
        {
            Console.WriteLine(p);
        }
    }
    
    0 讨论(0)
提交回复
热议问题