Skip to content

Instantly share code, notes, and snippets.

@emadb
Last active August 29, 2015 14:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save emadb/50f859df510c3f9d528d to your computer and use it in GitHub Desktop.
Save emadb/50f859df510c3f9d528d to your computer and use it in GitHub Desktop.
Run a set of tasks and wait for the first (in run order) that succeed
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
new Runner().Run();
Console.ReadLine();
}
}
public class Runner
{
private IList<ICalculator> _calculators;
private List<KeyValuePair<int, Task<int>>> _calculatorDictionary;
private int[] _calculatorResult;
private int _lastIndex = -1;
private int _finalResult;
public Runner()
{
_calculators = new List<ICalculator>{
new CalculatorErr(),
new GenericCalculator(1, 5000),
new GenericCalculator(2, 2000),
new GenericCalculator(3, 500),
new GenericCalculator(4, 500),
new GenericCalculator(5, 500),
new GenericCalculator(6, 500),
};
}
public void Run()
{
_calculatorDictionary = new List<KeyValuePair<int, Task<int>>>();
_calculatorResult = Enumerable.Repeat(0, _calculators.Count).ToArray(); ;
_calculators.EachWithIndex((c, i) =>
{
Task<int> t = c.Calculate(i);
t.ContinueWith(tt => callback(tt));
_calculatorDictionary.Add(new KeyValuePair<int, Task<int>>(t.GetHashCode(), t));
});
}
private void callback(Task<int> task)
{
int index = _calculatorDictionary.FindIndex(t => t.Key == task.GetHashCode());
if (!task.IsFaulted)
{
_calculatorResult[index] = task.Result;
}
else
{
_calculatorResult[index] = -1;
}
Console.WriteLine("Callback " + index + " isFaulted: " + task.IsFaulted + " Results: " + ToString(_calculatorResult));
bool allFaulted = true;
for (int i = index-1; i >= 0; i--)
{
allFaulted &= (_calculatorResult[i] == -1);
}
if (allFaulted && !task.IsFaulted)
{
_finalResult = task.Result;
Console.WriteLine("Final result (1): " + _finalResult);
}
if (allFaulted && task.IsFaulted)
{
_finalResult = _calculatorResult.FirstOrDefault(t => t != -1 && t != 0);
if (_finalResult != 0)
{
Console.WriteLine("Final result (2): " + _finalResult);
}
}
}
private string ToString(int[] _calculatorResult)
{
string result = "[";
_calculatorResult.Each(i =>
{
result += (i + ", ");
});
result = result.Remove(result.Length - 1) + "]";
return result;
}
}
public static class Extensions
{
public static void Each<T>(this IEnumerable<T> items, Action<T> action)
{
foreach (T item in items)
{
action(item);
}
}
public static void EachWithIndex<T>(this IEnumerable<T> items, Action<T, int> action)
{
int index = 0;
foreach (T item in items)
{
action(item, index);
index++;
}
}
}
public interface ICalculator
{
Task<int> Calculate(int x);
}
public class GenericCalculator : ICalculator
{
private int _wait;
private int _result;
public GenericCalculator(int result, int wait)
{
_wait = wait;
_result = result;
}
public Task<int> Calculate(int x)
{
return Task.Run(() =>
{
System.Threading.Thread.Sleep(_wait);
return _result;
});
}
}
public class CalculatorErr : ICalculator
{
public Task<int> Calculate(int x)
{
return Task.Run(() =>
{
System.Threading.Thread.Sleep(500);
throw new Exception();
return 3;
});
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment