Downloader 1000 for UWP (Windows App Store) using Windows 10 and .NET 4.6 Technologies

Start of Code Sample

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

using System.Diagnostics;
using System.Net;
using System.ComponentModel;

using System.Data;
using System.Text;
using Windows.UI.Popups;
using Windows.Storage;

using System.Threading;
using System.Threading.Tasks;
using Windows.Storage.Pickers;

using Windows.Networking.BackgroundTransfer;
using Windows.Web.Http;

// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409

/// <summary>
///  v1.0.1.0
/// </summary>
namespace Downloader_1000
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    /// 
    public sealed partial class MainPage : Page
    {
        Stopwatch sw1 = new Stopwatch();
        double progress = 0d;
        long previousElapsedMilliseconds = 0;
        ulong previousBytesReceived = 0;

        DownloadOperation downloadOperation;
        CancellationTokenSource cancellationToken;
        Windows.Networking.BackgroundTransfer.BackgroundDownloader backgroundDownloader = new Windows.Networking.BackgroundTransfer.BackgroundDownloader();

        public MainPage()
        {
            this.InitializeComponent();
            /// this.Loaded += MainPage_Loaded;
            buttonStop.IsEnabled = false;
        }

        public async void Download()
        {
            sw1.Start();

            FolderPicker folderPicker = new FolderPicker();
            folderPicker.SuggestedStartLocation = PickerLocationId.Downloads;
            folderPicker.ViewMode = PickerViewMode.Thumbnail;
            folderPicker.FileTypeFilter.Add("*");
            StorageFolder folder = await folderPicker.PickSingleFolderAsync();
            if (folder != null)
            {
                StorageFile file = await folder.CreateFileAsync("DOWNLOADING.DAT", CreationCollisionOption.GenerateUniqueName);
                Uri URL = new Uri(textBoxURL.Text.ToString());
                downloadOperation = backgroundDownloader.CreateDownload(URL, file);
                Progress<DownloadOperation> progress = new Progress<DownloadOperation>(progressChanged);
                cancellationToken = new CancellationTokenSource();

                /// HandleDownloadAsync(downloadOperation, true);

                try
                {
                    buttonStop.IsEnabled = true;
                    statusText.Text = "Initializing...";

                    // cancellationToken.Cancel();

                    await downloadOperation.StartAsync().AsTask(cancellationToken.Token, progress);
                    outputView.Text = downloadOperation.StartAsync().GetResults().ToString();
                }
                catch (TaskCanceledException TCEx)
                {
                    statusText.Text = TCEx.ToString();
                    downloadOperation.ResultFile.DeleteAsync(); // Not awaited
                    downloadOperation = null;
                }
                catch(Exception ex)
                {
                    statusText.Text = ex.ToString();
                    downloadOperation.ResultFile.DeleteAsync(); // Not awaited
                    downloadOperation = null;
                }
            }
        }
        private void progressChanged(DownloadOperation downloadOperation)
        {
            /// Update the OutputView Text!!!
            /// outputView.Text = downloadOperation.StartAsync().GetResults().ToString();
            /* An exception of type 'System.Runtime.InteropServices.COMException' occurred in Downloader-1000.exe but was not handled in user code
               WinRT information: This operation was already started.Call AttachAsync to attach to a running download/ upload.
               Additional information: A method was called at an unexpected time. */

            // Update the label with how much data have been downloaded so far and the total size of the file we are currently downloading
            textBlockDownloaded.Text = string.Format("{0} MB / {1} MB",
                (downloadOperation.Progress.BytesReceived / 1024d / 1024d).ToString("0.000"),
                (downloadOperation.Progress.TotalBytesToReceive / 1024d / 1024d).ToString("0.000"));

            // Calculate download speed and output it to labelSpeed.
            const double duration = 3000D;
            double downloadSpeed = (downloadOperation.Progress.BytesReceived - previousBytesReceived) / 1024d * ((sw1.ElapsedMilliseconds - previousElapsedMilliseconds) / duration);
            if ((sw1.ElapsedMilliseconds - previousElapsedMilliseconds) >= duration)
            {
                textBlockSpeed.Text = string.Format("{0} KB/sec", (downloadSpeed).ToString("0.000"));
                previousBytesReceived = downloadOperation.Progress.BytesReceived;
                previousElapsedMilliseconds = sw1.ElapsedMilliseconds;
            }

            // Average Speed
            textBlockAvgSpeed.Text = string.Format("{0} KB/sec", (downloadOperation.Progress.BytesReceived / 1024d / sw1.ElapsedMilliseconds * 1000).ToString("0.000"));

            // Calculate Percentage to two decimal places
            float intermediate = (float)downloadOperation.Progress.BytesReceived / (float)downloadOperation.Progress.TotalBytesToReceive * 100;

            // Update the progressbar percentage only when the value is not the same.
            // progressBar1.Value = e.ProgressPercentage;
            progressBar1.Value = (int)(intermediate * 100);

            // Show the percentage on our label.
            // labelPercent.Text = e.ProgressPercentage.ToString("F2") + "%";
            textBlockPercent.Text = intermediate.ToString("F3") + "%";

            // Show Time Remaining
            textBlockTimeRemaining.Text = ((sw1.ElapsedMilliseconds / (double)downloadOperation.Progress.BytesReceived) * (downloadOperation.Progress.TotalBytesToReceive - downloadOperation.Progress.BytesReceived) / 1000).ToString("F3");

            // Show Time Elapsed
            textBlockTimeElapsed.Text = sw1.Elapsed.ToString();

            int progress = (int)(100 * ((double)downloadOperation.Progress.BytesReceived / (double)downloadOperation.Progress.TotalBytesToReceive));

            statusText.Text = String.Format("{0} of {1} kb. downloaded - {2}% complete.",
                downloadOperation.Progress.BytesReceived / 1024,
                downloadOperation.Progress.TotalBytesToReceive / 1024,
                progress);

            switch (downloadOperation.Progress.Status)
            {
                case BackgroundTransferStatus.Running:
                    {
                        break;
                    }
                case BackgroundTransferStatus.PausedByApplication:
                    {

                        break;
                    }
                case BackgroundTransferStatus.PausedCostedNetwork:
                    {

                        break;
                    }
                case BackgroundTransferStatus.PausedNoNetwork:
                    {

                        break;
                    }
                case BackgroundTransferStatus.Error:
                    {
                        statusText.Text = "An error occured while downloading.";
                        break;
                    }
            }
            if (downloadOperation.Progress.BytesReceived == downloadOperation.Progress.TotalBytesToReceive)        // This is no longer a dodgy test of >= 100 progress! :-)
            {
                if( downloadOperation == null )
                {
                    /// MessageBox.Show(e.Error.ToString());
                }

                // Adding basic error handling
                if (downloadOperation.Progress.Status == null)
                {
                    /// MessageBox.Show(e.Error.ToString());
                }

                // Reset the stopwatch.
                sw1.Stop();
                sw1.Reset();

                /*{
                    if (e.Cancelled == true)
                    {
                        /// MessageBox.Show("Download has been canceled.");
                    }
                    else
                    {
                        /// MessageBox.Show("Download completed!");
                    }
                }*/

                // Re-enable the Download Button
                buttonDownload.IsEnabled = true;
                downloadOperation.AttachAsync().Cancel();
                sw1.Stop();
                sw1.Reset();
                buttonDownload.IsEnabled = true;
                buttonStop.IsEnabled = false;
                statusText.Text = "Finished.";
            }
        }

        private void buttonDownload_Click(object sender, RoutedEventArgs e)
        {
            Download();
        }

        private void buttonStop_Click(object sender, RoutedEventArgs e)
        {
            /// Uri URL = new Uri(textBoxURL.Text.ToString());
            /// backgroundDownloader.CreateDownloadAsync(URL, downloadOperation.ResultFile,   );
            cancellationToken.Cancel();
            if (downloadOperation != null)
            {
                downloadOperation.AttachAsync().Cancel();
            }
            /// backgroundDownloader.CreateDownloadAsync().Cancel();
            sw1.Stop();
            sw1.Reset();
            buttonDownload.IsEnabled = true;
            buttonStop.IsEnabled = false;
            statusText.Text = "Stopped.";
        }
    }
}

End of Code Sample

Allocating 380.75GB

Allocating more RAM than my server has caused a crash in the ArmA 2 Game Server the other weekend… This is what happens when noobs are permitted to run scripts that spawn infinite objects.

Needless to say I only host the ArmA 2 Server on weekends now, and only upon a “heavy demand” request from the ArmA Community.

Arma2Server 380_75GB

My Overclock

I have run Prime95 for over 25 CPU Time hours on an overclock of 4600 MHz using an Intel Core i5 6600K processor.

The CPU voltage has been tweaked to a +0.400 Volts offset.

[Image]

Currently I cannot upload the ‘under 2MB’ .PNG screenshot due to a HTTP error in WordPress (the site just went live a few minutes ago).