Exemplo n.º 1
0
        /// <summary>
        ///   Run
        /// </summary>
        /// <param name="args"></param>
        public static void Run(string[] args)
        {
            if (args.Length < 3 || args.Length > 4)
            {
                Console.WriteLine($@"Usage:  {args[0]} <path> <folder> <IsOverwriten> [msbuild]");
                return;
            }

            Arguments        = args;
            IsMsBuildInvoked = Arguments.Length == 4 && Arguments[3] == "msbuild";

            var tokenSource = new CancellationTokenSource();
            var tasks       = new List <TaskEvent>();
            ConsoleCancelEventHandler onCancel = null;

            try
            {
                if (!IsMsBuildInvoked)
                {
                    var t0 = new TaskEvent
                    {
                        Name      = "t0",
                        Tag       = tasks,
                        OnRunning = async(sender, tea) =>
                        {
                            Console.WriteLine(@"Press `CTRL+C' to abort the process...");

                            onCancel = (o, e) =>
                            {
                                e.Cancel = true;
                                tea.TokenSource?.Cancel();
                            };

                            // Establish an event handler to process key press events.
                            Console.CancelKeyPress += onCancel;

                            while (!tea.TokenSource.IsCancellationRequested)
                            {
                                if (Console.KeyAvailable)
                                {
                                    Console.ReadKey(true);
                                }
                                else
                                {
                                    await Task.Delay(250, tea.TokenSource.Token);
                                }
                            }
                        },
                        OnExited = (sender, tea) =>
                        {
                            tea.Task.Dispose();
                            (tea.Tag as List <TaskEvent>)?.Remove((sender as ExitedEvent)?.TaskEvent);
                        }
                    };

                    tasks.Add(t0);
                    t0.AsyncMonitor();
                }

                // =================================================================================

                var t1 = new TaskEvent
                {
                    Name      = "t1",
                    Tag       = tasks,
                    OnRunning = (sender, tea) =>
                    {
                        var options = new ParallelOptions
                        {
                            MaxDegreeOfParallelism = Environment.ProcessorCount,
                            CancellationToken      = tea.TokenSource.Token
                        };
                        var cardCount = InitializeCollection(out var setCollection);

                        CreateResources(args, options, setCollection);

                        var dlCount = setCollection.Sum(kvp => kvp.Value.DownloadCount);
                        Console.WriteLine($@"Downloaded information for ({dlCount}/{cardCount}) file{(cardCount > 1 ? "s" : string.Empty)}.");
                    },
                    OnExited = (sender, tea) =>
                    {
                        tea.Task.Dispose();
                        (tea.Tag as List <TaskEvent>)?.Remove((sender as ExitedEvent)?.TaskEvent);
                    }
                };

                tasks.Add(t1);
                t1.AsyncMonitor();

                // Wait for any the tasks to finish and send the other one a cancellation signal.
                var b = Task.WaitAny(tasks.Select(x => x.Task).ToArray(), tokenSource.Token);
                if (b == 0)
                {
                    Console.CancelKeyPress -= onCancel;
                }
                tasks[tasks.Count > 1 && b == 0 ? 1 : 0].Cancel();
            } catch (OperationCanceledException)
            {
                Debug.WriteLine("");
            } catch (Exception ex)
            {
                Debug.Print("Exception messages:");
                var ie = ex.InnerException;
                while (ie != null)
                {
                    Debug.Print($"   {ie.GetType().Name}: {ie.Message}");
                    ie = ie.InnerException;
                }
            } finally
            {
                Task.WaitAll(tasks.Select(y => y.Task).ToArray());

                Debug.WriteLine(@"All Tasks Completed");

                tokenSource.Dispose();

                if (!IsMsBuildInvoked)
                {
                    Console.WriteLine(@"Press any key to continue...");
                    Console.ReadKey(true);
                }
            }
        }