Browse Source

Merge pull request #1727 from icsharpcode/aboutpagetcstoasync

TCS to async/await for AboutPage version checking code
pull/1728/head
Siegfried Pammer 6 years ago committed by GitHub
parent
commit
a1af0e5a06
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 117
      ILSpy/AboutPage.cs
  2. 4
      ILSpy/Commands/CheckForUpdatesCommand.cs
  3. 25
      ILSpy/MainWindow.xaml.cs

117
ILSpy/AboutPage.cs

@ -128,20 +128,19 @@ namespace ICSharpCode.ILSpy
button.Cursor = Cursors.Arrow; button.Cursor = Cursors.Arrow;
stackPanel.Children.Add(button); stackPanel.Children.Add(button);
button.Click += delegate { button.Click += async delegate {
button.Content = Resources.Checking; button.Content = Resources.Checking;
button.IsEnabled = false; button.IsEnabled = false;
GetLatestVersionAsync().ContinueWith(
delegate (Task<AvailableVersionInfo> task) { try {
try { AvailableVersionInfo vInfo = await GetLatestVersionAsync();
stackPanel.Children.Clear(); stackPanel.Children.Clear();
ShowAvailableVersion(task.Result, stackPanel); ShowAvailableVersion(vInfo, stackPanel);
} catch (Exception ex) { } catch (Exception ex) {
AvalonEditTextOutput exceptionOutput = new AvalonEditTextOutput(); AvalonEditTextOutput exceptionOutput = new AvalonEditTextOutput();
exceptionOutput.WriteLine(ex.ToString()); exceptionOutput.WriteLine(ex.ToString());
textView.ShowText(exceptionOutput); textView.ShowText(exceptionOutput);
} }
}, TaskScheduler.FromCurrentSynchronizationContext());
}; };
} }
@ -182,36 +181,25 @@ namespace ICSharpCode.ILSpy
} }
} }
static Task<AvailableVersionInfo> GetLatestVersionAsync() static async Task<AvailableVersionInfo> GetLatestVersionAsync()
{ {
var tcs = new TaskCompletionSource<AvailableVersionInfo>(); WebClient wc = new WebClient();
new Action(() => { IWebProxy systemWebProxy = WebRequest.GetSystemWebProxy();
WebClient wc = new WebClient(); systemWebProxy.Credentials = CredentialCache.DefaultCredentials;
IWebProxy systemWebProxy = WebRequest.GetSystemWebProxy(); wc.Proxy = systemWebProxy;
systemWebProxy.Credentials = CredentialCache.DefaultCredentials;
wc.Proxy = systemWebProxy; string data = await wc.DownloadStringTaskAsync(UpdateUrl);
wc.DownloadDataCompleted += delegate(object sender, DownloadDataCompletedEventArgs e) {
if (e.Error != null) { XDocument doc = XDocument.Load(new StringReader(data));
tcs.SetException(e.Error); var bands = doc.Root.Elements("band");
} else { var currentBand = bands.FirstOrDefault(b => (string)b.Attribute("id") == band) ?? bands.First();
try { Version version = new Version((string)currentBand.Element("latestVersion"));
XDocument doc = XDocument.Load(new MemoryStream(e.Result)); string url = (string)currentBand.Element("downloadUrl");
var bands = doc.Root.Elements("band"); if (!(url.StartsWith("http://", StringComparison.Ordinal) || url.StartsWith("https://", StringComparison.Ordinal)))
var currentBand = bands.FirstOrDefault(b => (string)b.Attribute("id") == band) ?? bands.First(); url = null; // don't accept non-urls
Version version = new Version((string)currentBand.Element("latestVersion"));
string url = (string)currentBand.Element("downloadUrl"); latestAvailableVersion = new AvailableVersionInfo { Version = version, DownloadUrl = url };
if (!(url.StartsWith("http://", StringComparison.Ordinal) || url.StartsWith("https://", StringComparison.Ordinal))) return latestAvailableVersion;
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;
} }
sealed class AvailableVersionInfo sealed class AvailableVersionInfo
@ -273,9 +261,7 @@ namespace ICSharpCode.ILSpy
void OnPropertyChanged(string propertyName) void OnPropertyChanged(string propertyName)
{ {
if (PropertyChanged != null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
} }
} }
@ -284,10 +270,10 @@ namespace ICSharpCode.ILSpy
/// Returns the download URL if an update is available. /// Returns the download URL if an update is available.
/// Returns null if no update is available, or if no check was performed. /// Returns null if no update is available, or if no check was performed.
/// </summary> /// </summary>
public static Task<string> CheckForUpdatesIfEnabledAsync(ILSpySettings spySettings) public static async Task<string> CheckForUpdatesIfEnabledAsync(ILSpySettings spySettings)
{ {
var tcs = new TaskCompletionSource<string>();
UpdateSettings s = new UpdateSettings(spySettings); UpdateSettings s = new UpdateSettings(spySettings);
// If we're in an MSIX package, updates work differently // If we're in an MSIX package, updates work differently
if (s.AutomaticUpdateCheckEnabled && !WindowsVersionHelper.HasPackageIdentity) { if (s.AutomaticUpdateCheckEnabled && !WindowsVersionHelper.HasPackageIdentity) {
// perform update check if we never did one before; // perform update check if we never did one before;
@ -296,40 +282,35 @@ namespace ICSharpCode.ILSpy
|| s.LastSuccessfulUpdateCheck < DateTime.UtcNow.AddDays(-7) || s.LastSuccessfulUpdateCheck < DateTime.UtcNow.AddDays(-7)
|| s.LastSuccessfulUpdateCheck > DateTime.UtcNow) || s.LastSuccessfulUpdateCheck > DateTime.UtcNow)
{ {
CheckForUpdateInternal(tcs, s); return await CheckForUpdateInternal(s);
} else { } else {
tcs.SetResult(null); return null;
} }
} else { } else {
tcs.SetResult(null); return null;
} }
return tcs.Task; return null;
} }
public static Task<string> CheckForUpdatesAsync(ILSpySettings spySettings) public static Task<string> CheckForUpdatesAsync(ILSpySettings spySettings)
{ {
var tcs = new TaskCompletionSource<string>();
UpdateSettings s = new UpdateSettings(spySettings); UpdateSettings s = new UpdateSettings(spySettings);
CheckForUpdateInternal(tcs, s); return CheckForUpdateInternal(s);
return tcs.Task;
} }
static void CheckForUpdateInternal(TaskCompletionSource<string> tcs, UpdateSettings s) static async Task<string> CheckForUpdateInternal(UpdateSettings s)
{ {
GetLatestVersionAsync().ContinueWith( try {
delegate (Task<AvailableVersionInfo> task) { var v = await GetLatestVersionAsync();
try { s.LastSuccessfulUpdateCheck = DateTime.UtcNow;
s.LastSuccessfulUpdateCheck = DateTime.UtcNow; if (v.Version > currentVersion)
AvailableVersionInfo v = task.Result; return v.DownloadUrl;
if (v.Version > currentVersion) else
tcs.SetResult(v.DownloadUrl); return null;
else } catch (Exception) {
tcs.SetResult(null); // ignore errors getting the version info
} catch (AggregateException) { return null;
// ignore errors getting the version info }
tcs.SetResult(null);
}
});
} }
} }

4
ILSpy/Commands/CheckForUpdatesCommand.cs

@ -34,9 +34,9 @@ namespace ICSharpCode.ILSpy
return base.CanExecute(parameter); 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);
} }
} }
} }

25
ILSpy/MainWindow.xaml.cs

@ -367,7 +367,7 @@ namespace ICSharpCode.ILSpy
SelectNode(node); SelectNode(node);
// only if not showing the about page, perform the update check: // only if not showing the about page, perform the update check:
ShowMessageIfUpdatesAvailableAsync(spySettings); await ShowMessageIfUpdatesAvailableAsync(spySettings);
} else { } else {
AboutPage.Display(decompilerTextView); AboutPage.Display(decompilerTextView);
} }
@ -501,20 +501,21 @@ namespace ICSharpCode.ILSpy
#region Update Check #region Update Check
string updateAvailableDownloadUrl; 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 // Don't check for updates if we're in an MSIX since they work differently
if (WindowsVersionHelper.HasPackageIdentity) { if (WindowsVersionHelper.HasPackageIdentity) {
return; return;
} }
Task<string> result; string downloadUrl;
if (forceCheck) { if (forceCheck) {
result = AboutPage.CheckForUpdatesAsync(spySettings); downloadUrl = await AboutPage.CheckForUpdatesAsync(spySettings);
} else { } 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) void updatePanelCloseButtonClick(object sender, RoutedEventArgs e)
@ -522,22 +523,22 @@ namespace ICSharpCode.ILSpy
updatePanel.Visibility = Visibility.Collapsed; updatePanel.Visibility = Visibility.Collapsed;
} }
void downloadOrCheckUpdateButtonClick(object sender, RoutedEventArgs e) async void downloadOrCheckUpdateButtonClick(object sender, RoutedEventArgs e)
{ {
if (updateAvailableDownloadUrl != null) { if (updateAvailableDownloadUrl != null) {
MainWindow.OpenLink(updateAvailableDownloadUrl); MainWindow.OpenLink(updateAvailableDownloadUrl);
} else { } else {
updatePanel.Visibility = Visibility.Collapsed; updatePanel.Visibility = Visibility.Collapsed;
AboutPage.CheckForUpdatesAsync(ILSpySettings.Load()) string downloadUrl = await AboutPage.CheckForUpdatesAsync(ILSpySettings.Load());
.ContinueWith(task => AdjustUpdateUIAfterCheck(task, true), TaskScheduler.FromCurrentSynchronizationContext()); AdjustUpdateUIAfterCheck(downloadUrl, true);
} }
} }
void AdjustUpdateUIAfterCheck(Task<string> task, bool displayMessage) void AdjustUpdateUIAfterCheck(string downloadUrl, bool displayMessage)
{ {
updateAvailableDownloadUrl = task.Result; updateAvailableDownloadUrl = downloadUrl;
updatePanel.Visibility = displayMessage ? Visibility.Visible : Visibility.Collapsed; updatePanel.Visibility = displayMessage ? Visibility.Visible : Visibility.Collapsed;
if (task.Result != null) { if (downloadUrl != null) {
updatePanelMessage.Text = Properties.Resources.ILSpyVersionAvailable; updatePanelMessage.Text = Properties.Resources.ILSpyVersionAvailable;
downloadOrCheckUpdateButton.Content = Properties.Resources.Download; downloadOrCheckUpdateButton.Content = Properties.Resources.Download;
} else { } else {

Loading…
Cancel
Save