0

I've got a button that adds a number of new tasks into my List<Task>.

List<Task> tasks = new List<Task>();

int repeatCount = X;
private void createTaskButton_Click(object sender, RoutedEventArgs e)
{
    for (int i = 0; i < repeatCount; i++)
        {
           tasks.Add(new Task(() => doMethod()));
        }
}

I would like to pass a different parameter into my method for each iteration. Could someone give me some examples on how this maybe possible please?

ie.

iteration 1 = doMethod(1);

iteration 2 = doMethod(2);

iteration 3 = doMethod(3);

Community
  • 1
  • 1
m00shii
  • 7
  • 5
  • Check out : http://stackoverflow.com/questions/41520513/create-a-task-with-an-actiont-t-n-multiple-parameters – Trey Mar 23 '17 at 21:05
  • It is not clear from your question where these parameters come from, or how `doMethod()` can accept parameters if, as the code you posted implies, it is declared without any parameters. But in any case, the marked duplicate explains that you can capture your parameters and pass them to the method easily, just by using normal method-calling syntax. Do note that if you want to pass the value of `i` in the above, you need to copy it to a variable declared _inside_ the `for` loop and pass that new variable instead of `i`. Otherwise, `i` might change before the method gets called. – Peter Duniho Mar 23 '17 at 21:10
  • Thank you for the responses. I am still very new to all of this and I was just open to suggestions on possibly solutions. I still do not understand the use of `actions` and calling my method from that but I will look into that and thank you for the direction. With regards to my method, it uses the parameter to basically determine the `task index` so it will update the value in a specific row. – m00shii Mar 23 '17 at 22:01

1 Answers1

0

Some of the Task constructors take a state argument. You could use that to pass state in a situation where you're changing the variable over time (i.e. you're in a loop). Something like this will do:

for (var i = 0; i < repeatCount; ++i)
    tasks.Add(new Task(o => doMethod((int) o)), i);
Michael Gunter
  • 12,528
  • 1
  • 24
  • 58
  • 1
    _"you're in a loop and can't capture the variable"_ -- when would that ever happen? – Peter Duniho Mar 23 '17 at 21:18
  • Edited to say "you're in a loop and can't readily capture the variable by value". – Michael Gunter Mar 23 '17 at 21:19
  • @MichaelGunter The answer to that is *still* "never". – Servy Mar 23 '17 at 21:20
  • 1
    _"can't readily capture the variable by value"_ -- when would that ever happen? – Peter Duniho Mar 23 '17 at 21:20
  • Fine. "you're in a loop" – Michael Gunter Mar 23 '17 at 21:20
  • 1
    @MichaelGunter Why would you ever want to do that over just using a closure? – Servy Mar 23 '17 at 21:21
  • Do what in particular? – Michael Gunter Mar 23 '17 at 21:22
  • So now you're boxing a value type, when it could just be captured and passed directly? What's the point in that? – Peter Duniho Mar 23 '17 at 21:22
  • @MichaelGunter What you're doing in your answer. – Servy Mar 23 '17 at 21:23
  • If you capture it directly, you capture by reference, therefore each Task gets a reference to a changing value. By passing it directly to the constructor, the value gets passed to the Task's function instead of the reference being captured. – Michael Gunter Mar 23 '17 at 21:24
  • @MichaelGunter You can create a local if you need to. It's simpler, and maintains static typing. – Servy Mar 23 '17 at 21:25
  • You can also do this. There are two options. This is just one of them. When I wrote this answer, there was already an answer demonstrating your suggestion. – Michael Gunter Mar 23 '17 at 21:27
  • Yes, you *can* do this. The question, which you have yet to actually answer, is why you would want to do this over the alternative. – Servy Mar 23 '17 at 21:32
  • For one, this is a one-liner. If your loop is actually something like `foreach (var o in a)` and your method takes an object, you can use these constructors without any additional variables or boxing, e.g., `foreach (var o in a) tasks.Add(new Task(doMethod, o));` – Michael Gunter Mar 23 '17 at 21:34
  • Also (and this is somewhat surprising), on the two machines I tested, the boxing solution outperforms the non-boxing solution, perhaps because it's slower to create the anonymous type that contains the closure. https://gist.github.com/Neuroboy23/b5fefe034d7d8da2cc89d9c08aabc262 – Michael Gunter Mar 23 '17 at 23:25