Last active
August 29, 2015 14:05
-
-
Save mrichman/551cc4d4a26305bebc8f to your computer and use it in GitHub Desktop.
Dependency and Execution Order in Asynchronous Operations http://stackoverflow.com/questions/25385129/dependency-and-execution-order-in-asynchronous-operations/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#region | |
using System; | |
using System.Collections.Generic; | |
using System.Threading.Tasks; | |
using Cmc.Core.ComponentModel; | |
using Cmc.Core.Diagnostics; | |
using Cmc.Installer.Core.Tasks; | |
#endregion | |
namespace Cmc.Installer.Core | |
{ | |
public abstract class Component | |
{ | |
protected readonly ILogger Logger; | |
protected readonly IProgress<InstallProgress> Progress; | |
private readonly Lazy<Task> _task; | |
protected Component(string name, string targetMachine, IProgress<InstallProgress> progress) | |
{ | |
Logger = ServiceLocator.Default.GetInstance<ILoggerFactory>().GetLogger(this); | |
Dependencies = new List<Component>(); | |
Name = name; | |
TargetMachine = targetMachine; | |
Progress = progress; | |
_task = new Lazy<Task>(StartTask); | |
} | |
protected string Name { get; set; } | |
protected string TargetMachine { get; set; } | |
protected IEnumerable<Component> Dependencies { get; set; } | |
public Task InstallationCompletion { get { return _task.Value; } } | |
protected abstract Task StartTask(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#region | |
using System; | |
using System.Linq; | |
using System.Threading; | |
using System.Threading.Tasks; | |
using Cmc.Installer.Agent.Client; | |
using Cmc.Installer.Core; | |
#endregion | |
namespace Cmc.Installer.Modules.Crm.Components | |
{ | |
public class TalismaServerComponent : Component | |
{ | |
public TalismaServerComponent(string targetMachine, IProgress<InstallProgress> progress, CancellationTokenSource cancellationTokenSource) | |
: base("Talisma Server", targetMachine, progress, cancellationTokenSource) | |
{ | |
} | |
protected override async Task StartTask(CancellationTokenSource cts) | |
{ | |
//Logger.Info("TalismaServerComponent.StartTask on " + TargetMachine); | |
// Don't start if we're cancelled already... | |
cts.Token.ThrowIfCancellationRequested(); | |
// Wait for dependencies to complete | |
await Task.WhenAll(Dependencies.Select(c => c.InstallationCompletion)); | |
// cts.Cancel() can cancel us in here - | |
// cts.Token.Throw... can abort if anything else was cancelled | |
// Install this component | |
try | |
{ | |
Logger.Info(string.Format("TalismaServerComponent installing on {0} here", TargetMachine)); | |
Thread.Sleep(3000); | |
} | |
catch (Exception ex) | |
{ | |
Logger.Error(ex.Message); | |
throw; | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#region | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Threading; | |
using System.Threading.Tasks; | |
using Cmc.Core.ComponentModel; | |
using Cmc.Core.Diagnostics; | |
using Cmc.Installer.Core; | |
using Cmc.Installer.Modules.Crm.Components; | |
#endregion | |
namespace TaskDependencyTest | |
{ | |
internal class Program | |
{ | |
private static void Main(string[] args) | |
{ | |
var logger = ServiceLocator.Default.GetInstance<ILoggerFactory>().GetLogger(typeof (Program)); | |
var cts = new CancellationTokenSource(); | |
var progressMachineA = new Progress<InstallProgress>(); | |
var progressMachineB = new Progress<InstallProgress>(); | |
var progressMachineC = new Progress<InstallProgress>(); | |
var serverOnMachineA = new TalismaServerComponent("CLTDEPAPI10", progressMachineA, cts); | |
var serverOnMachineB = new TalismaServerComponent("CLTDEPAPI11", progressMachineB, cts); | |
var appServerOnMachineB = new TalismaAppServerComponent("CLTDEPAPI11", progressMachineB, cts); | |
appServerOnMachineB.Dependencies.Add(serverOnMachineA); | |
var webComponentsOnMachineC = new TalismaWebComponentsComponent("CLTDEPFE1", progressMachineC, | |
cts); | |
// Set them up in arbitrary order, just like a user would do: | |
var componentsToInstall = new List<Component> | |
{ | |
appServerOnMachineB, | |
serverOnMachineA, | |
webComponentsOnMachineC, | |
serverOnMachineB | |
}; | |
try | |
{ | |
logger.Info("Starting {0} tasks", componentsToInstall.Count); | |
Task.WhenAll(componentsToInstall.Select(c => c.InstallationCompletion)); | |
} | |
catch (AggregateException ae) | |
{ | |
logger.Fatal(ae); | |
Console.WriteLine(@"Error: {0}", ae.Flatten()); | |
} | |
Console.Write("Installation complete. Press any key to exit."); | |
Console.ReadLine(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2014-08-22 11:47:20.2706 | INFO | Starting 4 tasks | |
2014-08-22 11:47:20.2816 | INFO | TalismaServerComponent installing on CLTDEPAPI10 here | |
2014-08-22 11:47:23.2819 | INFO | TalismaAppServerComponent installing on CLTDEPAPI11 here | |
2014-08-22 11:47:26.2832 | INFO | TalismaWebComponentsComponent installing on CLTDEPFE1 here | |
2014-08-22 11:47:29.2835 | INFO | TalismaServerComponent installing on CLTDEPAPI11 here | |
Installation complete. Press any key to exit. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment