diff --git a/ILSpy/AboutPage.cs b/ILSpy/AboutPage.cs index ca85a1c0d..1e6b1accf 100644 --- a/ILSpy/AboutPage.cs +++ b/ILSpy/AboutPage.cs @@ -129,20 +129,19 @@ namespace ICSharpCode.ILSpy button.Cursor = Cursors.Arrow; stackPanel.Children.Add(button); - button.Click += delegate { + button.Click += async delegate { button.Content = Resources.Checking; button.IsEnabled = false; - GetLatestVersionAsync().ContinueWith( - delegate (Task task) { - try { - stackPanel.Children.Clear(); - ShowAvailableVersion(task.Result, stackPanel); - } catch (Exception ex) { - AvalonEditTextOutput exceptionOutput = new AvalonEditTextOutput(); - exceptionOutput.WriteLine(ex.ToString()); - textView.ShowText(exceptionOutput); - } - }, TaskScheduler.FromCurrentSynchronizationContext()); + + try { + AvailableVersionInfo vInfo = await GetLatestVersionAsync(); + stackPanel.Children.Clear(); + ShowAvailableVersion(vInfo, stackPanel); + } catch (Exception ex) { + AvalonEditTextOutput exceptionOutput = new AvalonEditTextOutput(); + exceptionOutput.WriteLine(ex.ToString()); + textView.ShowText(exceptionOutput); + } }; } @@ -183,36 +182,25 @@ namespace ICSharpCode.ILSpy } } - static Task GetLatestVersionAsync() + static async Task GetLatestVersionAsync() { - var tcs = new TaskCompletionSource(); - new Action(() => { - WebClient wc = new WebClient(); - IWebProxy systemWebProxy = WebRequest.GetSystemWebProxy(); - systemWebProxy.Credentials = CredentialCache.DefaultCredentials; - wc.Proxy = systemWebProxy; - wc.DownloadDataCompleted += delegate(object sender, DownloadDataCompletedEventArgs e) { - if (e.Error != null) { - tcs.SetException(e.Error); - } else { - try { - XDocument doc = XDocument.Load(new MemoryStream(e.Result)); - var bands = doc.Root.Elements("band"); - var currentBand = bands.FirstOrDefault(b => (string)b.Attribute("id") == band) ?? bands.First(); - Version version = new Version((string)currentBand.Element("latestVersion")); - string url = (string)currentBand.Element("downloadUrl"); - if (!(url.StartsWith("http://", StringComparison.Ordinal) || url.StartsWith("https://", StringComparison.Ordinal))) - url = null; // don't accept non-urls - latestAvailableVersion = new AvailableVersionInfo { Version = version, DownloadUrl = url }; - tcs.SetResult(latestAvailableVersion); - } catch (Exception ex) { - tcs.SetException(ex); - } - } - }; - wc.DownloadDataAsync(UpdateUrl); - }).BeginInvoke(null, null); - return tcs.Task; + WebClient wc = new WebClient(); + IWebProxy systemWebProxy = WebRequest.GetSystemWebProxy(); + systemWebProxy.Credentials = CredentialCache.DefaultCredentials; + wc.Proxy = systemWebProxy; + + string data = await wc.DownloadStringTaskAsync(UpdateUrl); + + XDocument doc = XDocument.Load(new StringReader(data)); + var bands = doc.Root.Elements("band"); + var currentBand = bands.FirstOrDefault(b => (string)b.Attribute("id") == band) ?? bands.First(); + Version version = new Version((string)currentBand.Element("latestVersion")); + string url = (string)currentBand.Element("downloadUrl"); + if (!(url.StartsWith("http://", StringComparison.Ordinal) || url.StartsWith("https://", StringComparison.Ordinal))) + url = null; // don't accept non-urls + + latestAvailableVersion = new AvailableVersionInfo { Version = version, DownloadUrl = url }; + return latestAvailableVersion; } sealed class AvailableVersionInfo @@ -274,9 +262,7 @@ namespace ICSharpCode.ILSpy void OnPropertyChanged(string propertyName) { - if (PropertyChanged != null) { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); - } + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } @@ -285,10 +271,10 @@ namespace ICSharpCode.ILSpy /// Returns the download URL if an update is available. /// Returns null if no update is available, or if no check was performed. /// - public static Task CheckForUpdatesIfEnabledAsync(ILSpySettings spySettings) + public static async Task CheckForUpdatesIfEnabledAsync(ILSpySettings spySettings) { - var tcs = new TaskCompletionSource(); UpdateSettings s = new UpdateSettings(spySettings); + // If we're in an MSIX package, updates work differently if (s.AutomaticUpdateCheckEnabled && !WindowsVersionHelper.HasPackageIdentity) { // perform update check if we never did one before; @@ -297,40 +283,35 @@ namespace ICSharpCode.ILSpy || s.LastSuccessfulUpdateCheck < DateTime.UtcNow.AddDays(-7) || s.LastSuccessfulUpdateCheck > DateTime.UtcNow) { - CheckForUpdateInternal(tcs, s); + return await CheckForUpdateInternal(s); } else { - tcs.SetResult(null); + return null; } } else { - tcs.SetResult(null); + return null; } - return tcs.Task; + return null; } public static Task CheckForUpdatesAsync(ILSpySettings spySettings) { - var tcs = new TaskCompletionSource(); UpdateSettings s = new UpdateSettings(spySettings); - CheckForUpdateInternal(tcs, s); - return tcs.Task; + return CheckForUpdateInternal(s); } - static void CheckForUpdateInternal(TaskCompletionSource tcs, UpdateSettings s) + static async Task CheckForUpdateInternal(UpdateSettings s) { - GetLatestVersionAsync().ContinueWith( - delegate (Task task) { - try { - s.LastSuccessfulUpdateCheck = DateTime.UtcNow; - AvailableVersionInfo v = task.Result; - if (v.Version > currentVersion) - tcs.SetResult(v.DownloadUrl); - else - tcs.SetResult(null); - } catch (AggregateException) { - // ignore errors getting the version info - tcs.SetResult(null); - } - }); + try { + var v = await GetLatestVersionAsync(); + s.LastSuccessfulUpdateCheck = DateTime.UtcNow; + if (v.Version > currentVersion) + return v.DownloadUrl; + else + return null; + } catch (Exception) { + // ignore errors getting the version info + return null; + } } } diff --git a/ILSpy/Commands/CheckForUpdatesCommand.cs b/ILSpy/Commands/CheckForUpdatesCommand.cs index 7cae660d9..00480cc9f 100644 --- a/ILSpy/Commands/CheckForUpdatesCommand.cs +++ b/ILSpy/Commands/CheckForUpdatesCommand.cs @@ -34,9 +34,9 @@ namespace ICSharpCode.ILSpy return base.CanExecute(parameter); } - public override void Execute(object parameter) + public override async void Execute(object parameter) { - MainWindow.Instance.ShowMessageIfUpdatesAvailableAsync(ILSpySettings.Load(), forceCheck: true); + await MainWindow.Instance.ShowMessageIfUpdatesAvailableAsync(ILSpySettings.Load(), forceCheck: true); } } } diff --git a/ILSpy/MainWindow.xaml.cs b/ILSpy/MainWindow.xaml.cs index 5091e6c73..e020bbf7a 100644 --- a/ILSpy/MainWindow.xaml.cs +++ b/ILSpy/MainWindow.xaml.cs @@ -367,7 +367,7 @@ namespace ICSharpCode.ILSpy SelectNode(node); // only if not showing the about page, perform the update check: - ShowMessageIfUpdatesAvailableAsync(spySettings); + await ShowMessageIfUpdatesAvailableAsync(spySettings); } else { AboutPage.Display(decompilerTextView); } @@ -501,20 +501,21 @@ namespace ICSharpCode.ILSpy #region Update Check string updateAvailableDownloadUrl; - public void ShowMessageIfUpdatesAvailableAsync(ILSpySettings spySettings, bool forceCheck = false) + public async Task ShowMessageIfUpdatesAvailableAsync(ILSpySettings spySettings, bool forceCheck = false) { // Don't check for updates if we're in an MSIX since they work differently if (WindowsVersionHelper.HasPackageIdentity) { return; } - Task result; + string downloadUrl; if (forceCheck) { - result = AboutPage.CheckForUpdatesAsync(spySettings); + downloadUrl = await AboutPage.CheckForUpdatesAsync(spySettings); } else { - result = AboutPage.CheckForUpdatesIfEnabledAsync(spySettings); + downloadUrl = await AboutPage.CheckForUpdatesIfEnabledAsync(spySettings); } - result.ContinueWith(task => AdjustUpdateUIAfterCheck(task, forceCheck), TaskScheduler.FromCurrentSynchronizationContext()); + + AdjustUpdateUIAfterCheck(downloadUrl, forceCheck); } void updatePanelCloseButtonClick(object sender, RoutedEventArgs e) @@ -522,22 +523,22 @@ namespace ICSharpCode.ILSpy updatePanel.Visibility = Visibility.Collapsed; } - void downloadOrCheckUpdateButtonClick(object sender, RoutedEventArgs e) + async void downloadOrCheckUpdateButtonClick(object sender, RoutedEventArgs e) { if (updateAvailableDownloadUrl != null) { MainWindow.OpenLink(updateAvailableDownloadUrl); } else { updatePanel.Visibility = Visibility.Collapsed; - AboutPage.CheckForUpdatesAsync(ILSpySettings.Load()) - .ContinueWith(task => AdjustUpdateUIAfterCheck(task, true), TaskScheduler.FromCurrentSynchronizationContext()); + string downloadUrl = await AboutPage.CheckForUpdatesAsync(ILSpySettings.Load()); + AdjustUpdateUIAfterCheck(downloadUrl, true); } } - void AdjustUpdateUIAfterCheck(Task task, bool displayMessage) + void AdjustUpdateUIAfterCheck(string downloadUrl, bool displayMessage) { - updateAvailableDownloadUrl = task.Result; + updateAvailableDownloadUrl = downloadUrl; updatePanel.Visibility = displayMessage ? Visibility.Visible : Visibility.Collapsed; - if (task.Result != null) { + if (downloadUrl != null) { updatePanelMessage.Text = Properties.Resources.ILSpyVersionAvailable; downloadOrCheckUpdateButton.Content = Properties.Resources.Download; } else {