Reputation: 9940
I have this code:
public async Task Execute()
{
_count = 0;
_total = 2; //I need to update this every time I add a new code block below.
//1st code block
_progressCallback("Downloading Inspections", _count / _total);
//do stuff
_count += 1;
//2nd code block
_progressCallback("Downloading Profiles", _count / _total);
//do stuff
_count += 1;
}
I need to keep adding more code blocks, which means I need to keep updating _total
.
I thought about doing something like so I don't need to keep updating _total
, I can get it from the Count of the List<Action>
:
List<Action> functions = new List<Action>();
functions.Add(() => FirstCodeBlock(_count, functions.Count));
Obviously this won't work because functions.Count
is only accurate after all the Action
s have been added.
Is there some way of writing this code so that I can add blocks of code without having to remember to update _total
?
Upvotes: 0
Views: 312
Reputation: 117185
Your code should work fine. The () => FirstCodeBlock(_count, functions.Count)
is only executed when you invoke the action. Try this example code:
List<Action> functions = new List<Action>();
functions.Add(() => Console.WriteLine(functions.Count));
functions.Add(() => Console.WriteLine(functions.Count));
functions.Add(() => Console.WriteLine(functions.Count));
functions.ForEach(function => function());
When I run this I get this:
3 3 3
Upvotes: 1
Reputation: 52290
Just populate the list ahead of time.
If you store your actions in a Dictionary<string,Action>
you can store the messages in there too, which makes it easier to iterate over them in a general fashion.
public void DownloadInspections()
{
//Code goes here
}
public void DownloadProfiles()
{
//Code goes here
}
public async Task Execute()
{
var list = new Dictionary<string,Action>
{
{ "Downloading inspections", DownloadInspections },
{ "Downloading profiles", DownloadProfiles }
};
foreach (var item in list)
{
//Display progress using the string included as the dictionary entry's key
_progressCallback(item.Key, _count++ / list.Count);
//Execute the action, which is stored in the dictionary entry's value
item.Value();
}
}
Upvotes: 1
Reputation: 590
Your List approach seems like it should work. functions.Count
in the lambda isn't evaluated until the lambda is invoked, so if you add all of the actions before you start invoking them, you should be fine.
This is an example of a closure. Since functions
is declared outside of the lambda, the compiler does some magic to allow it to be evaluated at invocation time.
Upvotes: 1
Reputation: 31721
This assumes you don't need _count
in the activities block,otherwise remove the _count++ / _total
.
Because you always have to describe/specify the string'ed named operations, use that as your total. And keep to the pattern.
int _count = 0;
var operations = new List<string>()
{
"Downloading Inspections",
"Downloading Profiles"
};
var _total = operations.Count();
_progressCallback(operations[_count], _count++ / _total);
...
_progressCallback(operations[_count], _count++ / _total);
...
Upvotes: 0