Call asynchronous method in constructor

 1 using System;
 2 using System.ComponentModel;
 3 using System.Threading.Tasks;
 4 public sealed class NotifyTaskCompletion<TResult> : INotifyPropertyChanged
 5 {
 6   public NotifyTaskCompletion(Task<TResult> task)
 7   {
 8     Task = task;
 9     if (!task.IsCompleted)
10     {
11       var _ = WatchTaskAsync(task);
12     }
13   }
14   private async Task WatchTaskAsync(Task task)
15   {
16     try
17     {
18       await task;
19     }
20     catch
21     {
22     }
23     var propertyChanged = PropertyChanged;
24     if (propertyChanged == null)
25         return;
26     propertyChanged(this, new PropertyChangedEventArgs("Status"));
27     propertyChanged(this, new PropertyChangedEventArgs("IsCompleted"));
28     propertyChanged(this, new PropertyChangedEventArgs("IsNotCompleted"));
29     if (task.IsCanceled)
30     {
31       propertyChanged(this, new PropertyChangedEventArgs("IsCanceled"));
32     }
33     else if (task.IsFaulted)
34     {
35       propertyChanged(this, new PropertyChangedEventArgs("IsFaulted"));
36       propertyChanged(this, new PropertyChangedEventArgs("Exception"));
37       propertyChanged(this,
38         new PropertyChangedEventArgs("InnerException"));
39       propertyChanged(this, new PropertyChangedEventArgs("ErrorMessage"));
40     }
41     else
42     {
43       propertyChanged(this,
44         new PropertyChangedEventArgs("IsSuccessfullyCompleted"));
45       propertyChanged(this, new PropertyChangedEventArgs("Result"));
46     }
47   }
48   public Task<TResult> Task { get; private set; }
49   public TResult Result { get { return (Task.Status == TaskStatus.RanToCompletion) ?
50     Task.Result : default(TResult); } }
51   public TaskStatus Status { get { return Task.Status; } }
52   public bool IsCompleted { get { return Task.IsCompleted; } }
53   public bool IsNotCompleted { get { return !Task.IsCompleted; } }
54   public bool IsSuccessfullyCompleted { get { return Task.Status ==
55     TaskStatus.RanToCompletion; } }
56   public bool IsCanceled { get { return Task.IsCanceled; } }
57   public bool IsFaulted { get { return Task.IsFaulted; } }
58   public AggregateException Exception { get { return Task.Exception; } }
59   public Exception InnerException { get { return (Exception == null) ?
60     null : Exception.InnerException; } }
61   public string ErrorMessage { get { return (InnerException == null) ?
62     null : InnerException.Message; } }
63   public event PropertyChangedEventHandler PropertyChanged;
64 }

An updated ViewModel using NotifyTaskCompletion<T> would look like this:

 
1 public class MainViewModel
2 {
3   public MainViewModel()
4   {
5     UrlByteCount = new NotifyTaskCompletion<int>(
6       MyStaticService.CountBytesInUrlAsync("http://www.example.com"));
7   }
8   public NotifyTaskCompletion<int> UrlByteCount { get; private set; }
9 }

 

 1 <Window x:Class="MainWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
 4   <Window.Resources>
 5     <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
 6   </Window.Resources>
 7   <Grid>
 8     <!-- Busy indicator -->
 9     <Label Content="Loading..." Visibility="{Binding UrlByteCount.IsNotCompleted,
10       Converter={StaticResource BooleanToVisibilityConverter}}"/>
11     <!-- Results -->
12     <Label Content="{Binding UrlByteCount.Result}" Visibility="{Binding
13       UrlByteCount.IsSuccessfullyCompleted,
14       Converter={StaticResource BooleanToVisibilityConverter}}"/>
15     <!-- Error details -->
16     <Label Content="{Binding UrlByteCount.ErrorMessage}" Background="Red"
17       Visibility="{Binding UrlByteCount.IsFaulted,
18       Converter={StaticResource BooleanToVisibilityConverter}}"/>
19   </Grid>
20 </Window>

From: https://msdn.microsoft.com/en-us/magazine/dn605875.aspx

posted @ 2017-06-15 16:19  WalterGao  阅读(204)  评论(0编辑  收藏  举报