/// <summary>
        /// Following are the functions that contain the logic that is executed once a button is pressed
        /// </summary>
        #region Buttons Logic
        private void SyncTest()
        {
            TotalTimeWatch.Start();

            //Initialize instances of Progress class that are later used to trigger
            //the events that update UI
            Progress <ImageTestReportModel> imageTestProgress = new Progress <ImageTestReportModel>();

            imageTestProgress.ProgressChanged += ImageTestProgressEvent;
            Progress <PNumTestReportModel> pNumTestProgress = new Progress <PNumTestReportModel>();

            pNumTestProgress.ProgressChanged += PNumTestProgressEvent;
            Progress <WebsitesTestReportModel> websitesTestProgress = new Progress <WebsitesTestReportModel>();

            websitesTestProgress.ProgressChanged += WebsitesTestProgressEvent;

            //Start executing each test sequentially
            ImageTestWatch.Start();
            ImageTest.StartSync(imageTestProgress);
            ImageTestWatch.Stop();
            ImageTestCheckmarkVisibility = Visibility.Visible;

            PNumTestWatch.Start();
            PrimeNumbersTest.StartSync(pNumTestProgress, pNumRangeTest, pNumNthTest);
            PNumTestWatch.Stop();
            PNumTestCheckmarkVisibility = Visibility.Visible;

            WebsitesTestWatch.Start();
            try
            {
                WebsitesTest.StartSync(websitesTestProgress);
                WebsitesTestCheckmarkVisibility = Visibility.Visible;
            }
            catch (WebException)
            {
                WebsitesTestProgressBarColour   = new SolidColorBrush(Colors.Red);
                WebsitesTestCrossmarkVisibility = Visibility.Visible;
            }
            WebsitesTestWatch.Stop();

            //Enable Reset button to let the user observe the results
            //and then reset UI before next run
            SyncBtnIsEnabled  = ParallelBtnIsEnabled = false;
            ResetBtnIsEnabled = true;

            //Stop Total timer and update all timers
            TotalTimeWatch.Stop();
            UpdateTimers(this, new EventArgs());

            //Push the results of execution to the results manager
            ResultsDataManager.SetResults("Synchronous", ImageTestTimerText, PNumTestTimerText, WebsitesTestTimerText, TotalTimeText, true);
        }
Example #2
0
        public static void Main(string[] args)
        {
            System.Console.WriteLine("Part 1 ...");
            var requestHelper = new RequestHelper("https://cpacodingchallenge.azurewebsites.net/api/results");
            var dataManager   = new ResultsDataManager(requestHelper);
            var resultsModel  = dataManager.GetSubjectResultsModelAsync().Result;

            foreach (var result in resultsModel.Results)
            {
                System.Console.WriteLine();
                System.Console.WriteLine(result.Key);
                System.Console.WriteLine(new string('-', 80));
                foreach (var subject in result.Value)
                {
                    System.Console.WriteLine(subject);
                }
            }

            //Part 2
            System.Console.WriteLine();
            System.Console.WriteLine();
            System.Console.WriteLine();
            System.Console.WriteLine("Part 2 ...");
            var originalData = dataManager.GetSubjectResultsDataAsync().Result;

            foreach (var data in originalData)
            {
                System.Console.WriteLine();
                System.Console.WriteLine(data.Subject);
                System.Console.WriteLine(new string('-', 80));
                foreach (var result in data.Results)
                {
                    System.Console.WriteLine("Year " + result.Year);
                    System.Console.WriteLine("Grade " + result.Grade);
                }
            }

            System.Console.ReadKey();
        }
        public ResultsWindowViewModel()
        {
            Results = new ObservableCollection <ResultsDataModel>(ResultsDataManager.GetResults());

            //Loop through all Results and populate ObservableCollections which are datasources for line chart
            int syncIndex          = 1;
            int asyncIndex         = 1;
            int parallelIndex      = 1;
            int parallelAsyncIndex = 1;

            for (int i = 0; i < Results.Count; i++)
            {
                //Add to the chart only the results of runs which were successfuly completed (e.g. not cancelled with "Cancel Operation" button)
                if (Results[i].CompletitionStatus == "Completed")
                {
                    if (Results[i].ExecutionType == "Synchronous")
                    {
                        SyncLS.Add(new KeyValuePair <int, int>(syncIndex++, Int32.Parse(Results[i].TotalTime.Replace(":", ""))));
                    }

                    else if (Results[i].ExecutionType == "Asynchronous")
                    {
                        AsyncLS.Add(new KeyValuePair <int, int>(asyncIndex++, Int32.Parse(Results[i].TotalTime.Replace(":", ""))));
                    }

                    else if (Results[i].ExecutionType == "Parallel")
                    {
                        ParallelLS.Add(new KeyValuePair <int, int>(parallelIndex++, Int32.Parse(Results[i].TotalTime.Replace(":", ""))));
                    }

                    else if (Results[i].ExecutionType == "Parallel + Async")
                    {
                        ParallelAsyncLS.Add(new KeyValuePair <int, int>(parallelAsyncIndex++, Int32.Parse(Results[i].TotalTime.Replace(":", ""))));
                    }
                }
            }
        }
        private async void ParallelAsyncTest()
        {
            //disable UI elements
            ResetUI();
            SyncBtnIsEnabled    = AsyncBtnIsEnabled = ParallelBtnIsEnabled = ParallelAsyncBtnIsEnabled = false;
            CancelBtnIsEnabled  = true;
            ParallelAsyncBtnTag = "Clicked";

            DTime.Start();
            TotalTimeWatch.Start();

            //Initialize instances of Progress class that are later used to trigger
            //the events that update UI
            Progress <ImageTestReportModel> imageTestProgress = new Progress <ImageTestReportModel>();

            imageTestProgress.ProgressChanged += ImageTestProgressEvent;
            Progress <PNumTestReportModel> pNumTestProgress = new Progress <PNumTestReportModel>();

            pNumTestProgress.ProgressChanged += PNumTestProgressEvent;
            Progress <WebsitesTestReportModel> websitesTestProgress = new Progress <WebsitesTestReportModel>();

            websitesTestProgress.ProgressChanged += WebsitesTestProgressEvent;


            //Start executing all 3 tests asynchronously and in parallel
            Task ImageTestTask = Task.Run(async() =>
            {
                try
                {
                    ImageTestWatch.Start();
                    await ImageTest.StartAsync(imageTestProgress, cts.Token);
                    ImageTestCheckmarkVisibility = Visibility.Visible;
                    ImageTestWatch.Stop();
                }
                catch (OperationCanceledException)
                {
                    //Call dispatcher to update UI from worker thread
                    Application.Current.Dispatcher.Invoke(() =>
                    {
                        ImageTestProgressBarColour   = new SolidColorBrush(Colors.Red);
                        ImageTestCrossmarkVisibility = Visibility.Visible;
                        CancelBtnTag = null;
                    });
                }
            });

            Task NthNumberTestTask = Task.Run(async() =>
            {
                try
                {
                    PNumTestWatch.Start();
                    await PrimeNumbersTest.StartParallelAsync(pNumTestProgress, pNumRangeTest, pNumNthTest, cts.Token);
                    PNumTestWatch.Stop();
                    PNumTestCheckmarkVisibility = Visibility.Visible;
                }
                catch (OperationCanceledException)
                {
                    Application.Current.Dispatcher.Invoke(() =>
                    {
                        PNumTestProgressBarColour   = new SolidColorBrush(Colors.Red);
                        PNumTestCrossmarkVisibility = Visibility.Visible;
                        CancelBtnTag = null;
                    });
                }
            });

            Task WebsitesTestTask = Task.Run(async() =>
            {
                try
                {
                    WebsitesTestWatch.Start();
                    await WebsitesTest.StartParallelAsync(websitesTestProgress, cts.Token);
                    WebsitesTestWatch.Stop();
                    WebsitesTestCheckmarkVisibility = Visibility.Visible;
                }
                catch (Exception ex)
                {
                    Application.Current.Dispatcher.Invoke(() =>
                    {
                        if (ex is OperationCanceledException || ex is WebException)
                        {
                            WebsitesTestProgressBarColour   = new SolidColorBrush(Colors.Red);
                            WebsitesTestCrossmarkVisibility = Visibility.Visible;
                            CancelBtnTag = null;
                        }
                    });
                }
            });

            await Task.WhenAll(ImageTestTask, NthNumberTestTask, WebsitesTestTask);

            //enable UI elements
            AsyncBtnIsEnabled   = ParallelAsyncBtnIsEnabled = ResetBtnIsEnabled = true;
            CancelBtnIsEnabled  = false;
            ParallelAsyncBtnTag = null;

            //Force update UI to enable disabled buttons
            CommandManager.InvalidateRequerySuggested();

            TotalTimeWatch.Stop();
            DTime.Stop();

            //Push the results of execution to the results manager
            ResultsDataManager.SetResults("Parallel + Async", ImageTestTimerText, PNumTestTimerText, WebsitesTestTimerText, TotalTimeText, !cts.IsCancellationRequested);
        }
        private void ParallelTest()
        {
            TotalTimeWatch.Start();

            //Initialize instances of Progress class that are later used to trigger
            //the events that update UI
            Progress <ImageTestReportModel> imageTestProgress = new Progress <ImageTestReportModel>();

            imageTestProgress.ProgressChanged += ImageTestProgressEvent;
            Progress <PNumTestReportModel> pNumTestProgress = new Progress <PNumTestReportModel>();

            pNumTestProgress.ProgressChanged += PNumTestProgressEvent;
            Progress <WebsitesTestReportModel> websitesTestProgress = new Progress <WebsitesTestReportModel>();

            websitesTestProgress.ProgressChanged += WebsitesTestProgressEvent;

            //Functions and variables in Image test are highly dependent on each other, therefore
            //I didn't find an efficient way to implement parallel execution for this test.
            Task ImageTestTask = Task.Run(() =>
            {
                ImageTestWatch.Start();
                ImageTest.StartSync(imageTestProgress);
                ImageTestWatch.Stop();
                ImageTestCheckmarkVisibility = Visibility.Visible;
            });

            Task PNumTestTask = Task.Run(() =>
            {
                PNumTestWatch.Start();
                PrimeNumbersTest.StartParallel(pNumTestProgress, pNumRangeTest, pNumNthTest);
                PNumTestWatch.Stop();
                PNumTestCheckmarkVisibility = Visibility.Visible;
            });

            Task WebsitesTestTask = Task.Run(() =>
            {
                try
                {
                    WebsitesTestWatch.Start();
                    WebsitesTest.StartParallel(websitesTestProgress);
                    WebsitesTestWatch.Stop();
                    WebsitesTestCheckmarkVisibility = Visibility.Visible;
                }

                catch (WebException)
                {
                    WebsitesTestProgressBarColour   = new SolidColorBrush(Colors.Red);
                    WebsitesTestCrossmarkVisibility = Visibility.Visible;
                }
            });

            //Wait until all tasks are finished. UI thread is blocked.
            Task.WaitAll(ImageTestTask, PNumTestTask, WebsitesTestTask);

            //Enable Reset button to let the user observe the results
            //and then reset UI before next run
            SyncBtnIsEnabled  = ParallelBtnIsEnabled = false;
            ResetBtnIsEnabled = true;

            //Stop Total timer and update all timers
            TotalTimeWatch.Stop();
            UpdateTimers(this, new EventArgs());

            //Push the results of execution to the results manager
            ResultsDataManager.SetResults("Parallel", ImageTestTimerText, PNumTestTimerText, WebsitesTestTimerText, TotalTimeText, true);
        }
        private async void AsyncTest()
        {
            //disable UI elements
            ResetUI();
            SyncBtnIsEnabled   = AsyncBtnIsEnabled = ParallelBtnIsEnabled = ParallelAsyncBtnIsEnabled = false;
            CancelBtnIsEnabled = true;
            AsyncBtnTag        = "Clicked";

            DTime.Start();
            TotalTimeWatch.Start();

            //Initialize instances of Progress class that are later used to trigger
            //the events that update UI
            Progress <ImageTestReportModel> imageTestProgress = new Progress <ImageTestReportModel>();

            imageTestProgress.ProgressChanged += ImageTestProgressEvent;
            Progress <PNumTestReportModel> pNumTestProgress = new Progress <PNumTestReportModel>();

            pNumTestProgress.ProgressChanged += PNumTestProgressEvent;
            Progress <WebsitesTestReportModel> websitesTestProgress = new Progress <WebsitesTestReportModel>();

            websitesTestProgress.ProgressChanged += WebsitesTestProgressEvent;


            //Use try catch statement for cancellation Tokens
            try
            {
                ImageTestWatch.Start();
                await ImageTest.StartAsync(imageTestProgress, cts.Token);

                ImageTestWatch.Stop();
                ImageTestCheckmarkVisibility = Visibility.Visible;
            }
            catch (OperationCanceledException)
            {
                ImageTestProgressBarColour   = new SolidColorBrush(Colors.Red);
                ImageTestCrossmarkVisibility = Visibility.Visible;
                CancelBtnTag = null;
            }

            try
            {
                PNumTestWatch.Start();
                await PrimeNumbersTest.StartAsync(pNumTestProgress, pNumRangeTest, pNumNthTest, cts.Token);

                PNumTestWatch.Stop();
                PNumTestCheckmarkVisibility = Visibility.Visible;
            }
            catch (OperationCanceledException)
            {
                PNumTestProgressBarColour   = new SolidColorBrush(Colors.Red);
                PNumTestCrossmarkVisibility = Visibility.Visible;
                CancelBtnTag = null;
            }

            try
            {
                WebsitesTestWatch.Start();
                await WebsitesTest.StartAsync(websitesTestProgress, cts.Token);

                WebsitesTestWatch.Stop();
                WebsitesTestCheckmarkVisibility = Visibility.Visible;
            }
            catch (Exception ex)
            {
                if (ex is OperationCanceledException || ex is WebException)
                {
                    WebsitesTestProgressBarColour   = new SolidColorBrush(Colors.Red);
                    WebsitesTestCrossmarkVisibility = Visibility.Visible;
                    CancelBtnTag = null;
                }
            }

            //enable UI elements
            AsyncBtnIsEnabled  = ParallelAsyncBtnIsEnabled = ResetBtnIsEnabled = true;
            CancelBtnIsEnabled = false;
            AsyncBtnTag        = null;

            //Force update UI to enable disabled buttons
            CommandManager.InvalidateRequerySuggested();

            TotalTimeWatch.Stop();
            DTime.Stop();

            //Push the results of execution to the results manager
            ResultsDataManager.SetResults("Asynchronous", ImageTestTimerText, PNumTestTimerText, WebsitesTestTimerText, TotalTimeText, !cts.IsCancellationRequested);
        }