When operating on large data sets in .Net, there is frequently a need to cancel the operations.
	We have already determined the steady-state performance considerations of basic loop structures, but adding a cancellation check may change that.
	As determined before, Arrays are generally the faster structure except when using .Net's MoveNext().
	for loops are the fastest, followed closely by foreach.
	This quick study hopes to see if there is any change in which to select based on the use of a cancellation token.
	
	Let's try a few approaches to implementation that will demonstrate the differences:
/// <summary>
/// Runs a test of each Loop given a number of items
/// </summary>
/// <param name="numberOfItems">The number of items</param>
/// <returns>Returns an array of results</returns>
public static long[] Run(int numberOfItems)
{
	var ret = new long[6];
	var sw = new System.Diagnostics.Stopwatch();
	var testList = MakeTestList(numberOfItems);
	var token = default(CancellationToken);
	// for loop on List
	var current = 0;
	sw.Start();
	for (int i = 0; !token.IsCancellationRequested && i < numberOfItems; i++)
	{
		current += testList[i];
	}
	sw.Stop();
	ret[0] = sw.Elapsed.Ticks;
	// foreach loop on List
	current = 0;
	sw.Restart();
	foreach (var val in testList)
	{
		if (token.IsCancellationRequested) break;
		current += val;
	}
	sw.Stop();
	ret[1] = sw.Elapsed.Ticks;
	// enumerator MoveNext on List
	current = 0;
	sw.Restart();
	var enumerator = testList.GetEnumerator();
	while (!token.IsCancellationRequested && enumerator.MoveNext())
	{
		current += enumerator.Current;
	}
	sw.Stop();
	ret[2] = sw.Elapsed.Ticks;
	var testArray = MakeTestArray(numberOfItems);
	current = 0;
	// for loop on Array
	sw.Restart();
	for (int i = 0; !token.IsCancellationRequested && i < numberOfItems; i++)
	{
		current += testArray[i];
	}
	sw.Stop();
	ret[3] = sw.Elapsed.Ticks;
	current = 0;
	// foreach loop on Array
	sw.Restart();
	foreach (var val in testArray)
	{
		if (token.IsCancellationRequested) break;
		current += val;
	}
	sw.Stop();
	ret[4] = sw.Elapsed.Ticks;
	// enumerator MoveNext on Array
	current = 0;
	sw.Restart();
	var aenumerator = testArray.GetEnumerator();
	while (!token.IsCancellationRequested && aenumerator.MoveNext())
	{
		current += (int)aenumerator.Current;
	}
	sw.Stop();
	ret[5] = sw.Elapsed.Ticks;
	return ret;
}
Here is the average of 30 runs (all times in Ticks):
Average Time (in ticks) to access N number of items
| items | for (List) | foreach (List) | enumerator (List) | for (Array) | foreach (Array) | enumerator (Array) | 
|---|---|---|---|---|---|---|
| 1 | 2.03361344537815 | 3.15966386554621 | 1.66666666666666 | 1.6 | 1.36666666666666 | 8.45378151260504 | 
| 2 | 2.23333333333333 | 3.85 | 1.94166666666666 | 1.96666666666666 | 1.73333333333333 | 7.06666666666666 | 
| 4 | 2.00833333333333 | 3.99166666666666 | 2.41666666666666 | 2.2 | 1.43333333333333 | 8.025 | 
| 8 | 2.83333333333333 | 4.59166666666666 | 2.57627118644067 | 2.34166666666666 | 1.83333333333333 | 13.2083333333333 | 
| 16 | 3.75 | 5.74166666666666 | 3.46666666666666 | 2.56666666666666 | 2.63333333333333 | 21.8547008547008 | 
| 32 | 5.81666666666666 | 8.56666666666666 | 7.225 | 4.74166666666666 | 4.83333333333333 | 51.798319327731 | 
| 64 | 9.54166666666666 | 12.575 | 10.7333333333333 | 6.98333333333333 | 7.28333333333333 | 73.054054054054 | 
| 128 | 13.8083333333333 | 19.8916666666666 | 18.9166666666666 | 10.5916666666666 | 11.3333333333333 | 131.552631578947 | 
| 256 | 25.1826086956521 | 36.6333333333333 | 37.1333333333333 | 21.3 | 22.5 | 267.306306306306 | 
| 512 | 49.895652173913 | 65.099099099099 | 68.6271186440677 | 38.2068965517241 | 42.0086206896551 | 586.798319327731 | 
| 1024 | 97.6521739130434 | 130.149122807017 | 135.701754385964 | 75.5 | 82.9652173913043 | 1082.64912280701 | 
| 2048 | 196.310344827586 | 257.173913043478 | 271.163793103448 | 150.700854700854 | 166.871794871794 | 2137.36936936936 | 
| 4096 | 392.625 | 507.410714285714 | 540.9375 | 296.6 | 334.060344827586 | 4226.71028037383 | 
| 8192 | 792.304347826087 | 1023.66371681415 | 1087.60526315789 | 602.438596491228 | 661.859649122807 | 8677.02970297029 | 
| 16384 | 1533.7610619469 | 2037.64347826086 | 2184.00869565217 | 1194.5625 | 1327.34513274336 | 18045.4594594594 | 
| 32768 | 3134.68965517241 | 4098.40517241379 | 4372.20175438596 | 2411.18018018018 | 2658.22123893805 | 35156.2432432432 | 
| 65536 | 6259.08620689655 | 8147.83478260869 | 8693.79646017699 | 4785.67272727272 | 5292.78181818181 | 69850.7663551402 | 
| 131072 | 12254.4385964912 | 16153.4545454545 | 17381.8 | 9782.63063063063 | 10798.0982142857 | 142121.089285714 | 
| 262144 | 25424.6902654867 | 33068.6666666666 | 35065.9082568807 | 19155.1666666666 | 21315.0091743119 | 288966.622807017 | 
| 524288 | 50529.0982142857 | 65797.5575221239 | 70636.6194690265 | 39647.0683760683 | 43569.3063063063 | 577622.45045045 | 
| 1048576 | 101330.371681415 | 131997.855855855 | 140286.254716981 | 77389.3008849557 | 85306.7207207207 | 1148081.91452991 | 
| 2097152 | 204322.308411214 | 267888.166666666 | 281648.897196261 | 155159.216216216 | 173218.116071428 | 2301453.94642857 | 
Now, normalize the times to ticks per item.
Normalized Average Time (with respect to ticks / item)
| items | for (List) | foreach (List) | enumerator (List) | for (Array) | foreach (Array) | enumerator (Array) | 
|---|---|---|---|---|---|---|
| 4 | 0.508403361344537 | 0.789915966386552 | 0.416666666666665 | 0.4 | 0.341666666666665 | 2.11344537815126 | 
| 8 | 0.279166666666666 | 0.48125 | 0.242708333333332 | 0.245833333333332 | 0.216666666666666 | 0.883333333333333 | 
| 16 | 0.125520833333333 | 0.249479166666666 | 0.151041666666666 | 0.1375 | 0.0895833333333331 | 0.5015625 | 
| 32 | 0.0885416666666666 | 0.143489583333333 | 0.0805084745762709 | 0.0731770833333331 | 0.0572916666666666 | 0.412760416666666 | 
| 64 | 0.05859375 | 0.0897135416666666 | 0.0541666666666666 | 0.0401041666666666 | 0.0411458333333333 | 0.3414797008547 | 
| 128 | 0.0454427083333333 | 0.0669270833333333 | 0.0564453125 | 0.0370442708333333 | 0.0377604166666666 | 0.404674369747898 | 
| 256 | 0.0372721354166666 | 0.04912109375 | 0.0419270833333332 | 0.0272786458333333 | 0.0284505208333333 | 0.285367398648648 | 
| 512 | 0.0269694010416666 | 0.0388509114583332 | 0.0369466145833332 | 0.0206868489583332 | 0.0221354166666666 | 0.256938733552631 | 
| 1024 | 0.0245923913043478 | 0.0357747395833333 | 0.0362630208333333 | 0.02080078125 | 0.02197265625 | 0.261041314752252 | 
| 2048 | 0.0243631114130435 | 0.0317866694819819 | 0.0335093352754237 | 0.0186557112068965 | 0.0205120218211207 | 0.286522616859244 | 
| 4096 | 0.0238408627717391 | 0.0317746881853069 | 0.0331303111293857 | 0.0184326171875 | 0.0202551800271739 | 0.264318633497805 | 
| 8192 | 0.0239636651400862 | 0.0313932999320652 | 0.0331010489628232 | 0.0183961004273503 | 0.0203700921474358 | 0.260909346846846 | 
| 16384 | 0.0239639282226562 | 0.0309698922293527 | 0.0330162048339844 | 0.01810302734375 | 0.0203894253434806 | 0.257977922386098 | 
| 32768 | 0.0241792098335598 | 0.0312397374516037 | 0.0331910785875821 | 0.0183849669339364 | 0.0201983535498904 | 0.264801931853341 | 
| 65536 | 0.0234033365165237 | 0.0310919720193613 | 0.0333253279976222 | 0.0182275772094727 | 0.020253679393667 | 0.275351859427786 | 
| 131072 | 0.0239157841123383 | 0.0312683500092605 | 0.0333572521544339 | 0.0183958448805251 | 0.0202806185832066 | 0.268220849939294 | 
| 262144 | 0.0238765190387594 | 0.0310815230659816 | 0.0331642015845375 | 0.0182558926669034 | 0.0201903603293679 | 0.266459527416764 | 
| 524288 | 0.0233734867029022 | 0.0308102694424715 | 0.0331531524658203 | 0.018658887158643 | 0.0205957378659929 | 0.27107446534293 | 
| 1048576 | 0.0242468741087787 | 0.0315367380777994 | 0.033441456086045 | 0.0182677904764811 | 0.0203275768035048 | 0.275580046469705 | 
| 2097152 | 0.0240941515990666 | 0.0313747203455562 | 0.0336821648926861 | 0.0189051954155294 | 0.0207754642039806 | 0.275431847787118 | 
| 4194304 | 0.0241590432361162 | 0.0314707412376058 | 0.0334468495171025 | 0.0184510471546544 | 0.020338707142048 | 0.273724058754423 | 
| 8388608 | 0.0243571172250764 | 0.0319347580273945 | 0.0335751649375273 | 0.0184964199323912 | 0.0206492085541997 | 0.274354689887592 | 
Show the results on a log2 - log2 plot...
 
	At first, we see that adding the cancellation check has also added ~20 nanoseconds (there are 100 nanoseconds / tick).
	As expected, for and foreach loops on Arrays are fastest.
	Using the enumerator's MoveNext() on the List is slower than calling foreach, but not by much - and this gap is narrower then when not checking for a cancellation.
	The enumerator with MoveNext() as it is always slower.
The Array enumerator is still the slowest.
	In conclusion, adding a cancellation check does not change the selection of a loop type.
	It is still recommended to use for loops, then foreach loops, then enumerators MoveNext().
