static void Main(string[] args)
        {
            Log(string.Format("Wonka Agent version: {0}", "1.1.0"));

            var taskDefinitionModel = GetDefinition(ConfigurationManager.AppSettings["task"]).Result;
            var tasks = GetTasks(taskDefinitionModel).Result;


            string runPath = string.Empty;

            try
            {
                runPath = InitialiseAgent(taskDefinitionModel);
            }
            catch (Exception e)
            {
                HandleException(e);
            }

            var taskRunner = new TaskRunner(runPath);

            taskRunner.TaskStatus += (e) =>
            {
                Log(e.Status);
            };

            taskRunner.TasksCompleted += (e) =>
            {
                Log("task completed");


                if (e.Status == TaskStatus.Faulted.ToString())
                {
                    Log("task faulted");
                }
                else
                {
                    Log("task completed - finished");
                }
            };


            try
            {
                Task bootstrapTask;
                CancellationTokenSource _b_cts = new CancellationTokenSource();
                var         bootstrapToken     = _b_cts.Token;
                List <Task> bootstrapTasks     = new List <Task>();
                bootstrapTask = new Task(() =>
                {
                    taskRunner.Run(bootstrapToken, tasks);
                });

                bootstrapTask.Start();
                Console.Write("waiting for bootstrap task runner...");
                bootstrapTask.Wait();
                Console.Write("finished waiting for bootstrap task runner...");

                Task t1;
                CancellationTokenSource _cts = new CancellationTokenSource();
                var token = _cts.Token;
                taskDefinitionModel.Path = runPath;
                var localtasks = LoadTasks(taskDefinitionModel);
                t1 = new Task(() =>
                {
                    taskRunner.Run(token, localtasks);
                });


                t1.Start();
                Console.Write("waiting for task runner...");
                t1.Wait();
                Console.Write("finished waiting for task runner...");
            }
            catch (DevOpsTaskException ex)
            {
                HandleException(ex);
            }
            catch (AggregateException ag)
            {
                HandleException(ag);
            }
            catch (Exception ex)
            {
                HandleException(ex);
            }
            finally
            {
                var taskState = taskRunner.GetDevOpsTaskWithState();
            }

            Log("Agent complete...");
        }
        public ActionResult Run(TaskModel taskModel)
        {
            var startTime = DateTime.Now;

            Session.Clear();

            AddMessage(BuildResources.Status_StartingBuild);
            string runPath = string.Empty;

            try
            {
                runPath = InitialiseBuildRun(taskModel.Path, taskModel.Project);

                Session[WebConfigurationManager.AppSettings[SESSION_KEY_RUN_PATH]] = runPath;
                Session[WebConfigurationManager.AppSettings[TASK_NAME]]            = taskModel.Task;
            }
            catch (Exception e)
            {
                HandleException(e);
                return(PartialView("_TasksFail"));
            }


            var taskRunner = new TaskRunner(runPath);

            taskRunner.TaskStatus += (e) =>
            {
                AddMessage(e.Status);
            };

            taskRunner.TasksCompleted += (e) =>
            {
                while (Broadcaster.Instance.MessageCount > 1)
                {
                    Thread.Sleep(2000);
                }

                if (e.Status == TaskStatus.Faulted.ToString())
                {
                    System.IO.File.Create(Path.Combine(runPath, WebConfigurationManager.AppSettings[ERROR_DATA_FILE]));
                }
                else
                {
                    var timeTaken = DateTime.UtcNow - startTime;
                    System.IO.File.Create(Path.Combine(runPath, WebConfigurationManager.AppSettings[COMPLETED_DATA_FILE]));

                    //ToDo:
                    //FileClient.WriteTextToFile(Path.Combine(runPath, COMPLETED_DATA_FILE), timeTaken.ToString());
                }
            };

            string tasksPath = string.Empty;

            try
            {
                CancellationTokenSource _cts = new CancellationTokenSource();
                var token = _cts.Token;

                Task t1 = new Task(() =>
                {
                    var path = Path.Combine(runPath, WebConfigurationManager.AppSettings[PROCESSING_DATA_FILE]);
                    System.IO.File.Create(Path.Combine(runPath, WebConfigurationManager.AppSettings[PROCESSING_DATA_FILE]));

                    tasksPath = Path.Combine(runPath, taskModel.FullName);

                    taskRunner.Run(token, Path.Combine(tasksPath));
                });

                Task t2 = t1.ContinueWith((ante) =>
                {
                }, TaskScheduler.FromCurrentSynchronizationContext());

                t1.Start();
            }
            catch (DevOpsTaskException ex)
            {
                HandleException(ex);
                return(PartialView("_TasksFail"));
            }
            catch (AggregateException ag)
            {
                HandleException(ag);
                return(PartialView("_TasksFail"));
            }
            catch (Exception ex)
            {
                HandleException(ex);
                return(PartialView("_TasksFail"));
            }
            finally
            {
                var tasks = taskRunner.GetDevOpsTaskWithState();
                //could serialize the state back to the tasks file for verification
                //taskRunner.S.SerializeTasksToFile(tasks, ConfigurationManager.AppSettings["tasksPath"]);
            }

            var model = new TaskInformationModel()
            {
                TaskName       = taskModel.Task,
                TasksPath      = taskModel.Path,
                TasksStartTime = startTime.ToString(),
            };

            return(PartialView("_TasksRunning", model));
        }