2012-11-29 7 views
5

mam niestandardowej klasy (w celu uproszczenia rzeczy, mam okrojona kody):Wywołanie Awaitable Methods in Property Accessor [Windows Store apps/Metro aplikacje]

public class AlbumItem 
{ 
    public StorageFile AlbumThumbnail { get; set;} 
} 

Kiedy wiążę to ListView:

<ListView.ItemTemplate> 
      <DataTemplate> 
       <Grid Height="100" Background="#FFabe372"> 
        <Grid.ColumnDefinitions> 
         <ColumnDefinition Width="80" /> 
         <ColumnDefinition Width="*" /> 
        </Grid.ColumnDefinitions> 
        <Image Source="{Binding AlbumSource}" Margin="10" Stretch="Uniform"></Image> 
        <TextBlock Margin="20 5" Grid.Column="1" Style="{StaticResource AlbumListViewItemStyle}" Text="{Binding AlbumDisplayText}"></TextBlock> 
       </Grid> 

      </DataTemplate> 
</ListView.ItemTemplate> 

source Image „s jest ustawiona na AlbumSource, jak myślałem do wdrożenia AlbumSource jako Get własności -tylko:

public class AlbumItem 
{ 
    public StorageFile AlbumThumbnail { get; set;} 

    public BitmapImage AlbumSource 
    { 
     get 
     { 
      BitmapImage bmp = new BitmapImage(); 
      bmp.SetSource(await AlbumThumbnail.OpenReadAsync()); 
      return bmp; 
     } 
    } 
} 

Zgodnie z oczekiwaniami nie mogę użyć słowa kluczowego await w metodzie akcesora, jednocześnie nie mogę zadeklarować kodu nieruchomości jako metody async.

Czy ktoś może wskazać mi właściwy kierunek? Być może próbuję później. Dzięki!

Odpowiedz

7

Osoby mające dostęp do IMHO powinny zawsze zwracać się niemal natychmiast. Długotrwałe operacje nie powinny być wykonywane wewnątrz elementu dostępowego właściwości, ponieważ może to mieć znaczny wpływ na wydajność z powodu powszechnie przyjętego założenia, że ​​accessor jest w zasadzie operacją odczytu zmiennego (tj. Właściwości mogą być dostępne dużo, w pętlach, nie buforowane dla późniejszego dostępu itp.).

zrobiłbym coś takiego:

private async Task SetAlbumSourceAsync() 
{ 
    bmp = new BitmapImage(); 
    var source = await AlbumThumbnail.OpenReadAsync(); 
    bmp.SetSource(source); 
    RaisePropertyChanged("AlbumSource"); 
} 

BitmapImage bmp; 
public BitmapImage AlbumSource 
{ 
    get 
    { 
     if (bmp == null) // might need a better sync mechanism to prevent reentrancy but you get the idea 
      SetAlbumSourceAsync(); 

     return bmp; 
    } 
} 
+0

dzięki! wpadłem na ten pomysł, ale metoda Flaviena rozwiązała moją natychmiastową potrzebę. Zbadam twoje podejście i zobaczę, czy uda mi się je zdobyć i pracować po tym. –

+2

+1 To jest poprawniejsza odpowiedź. Nie ma żadnego technicznego powodu, że właściwości 'asynchroniczne' nie mogą istnieć; była to decyzja projektowa, ponieważ "własność asynchroniczna" jest sprzeczna z samą koncepcją własności. –

+0

Tak, dotychczas wdrożyłem moje właściwości za pomocą tej metody, i tak, to nie dusi mojego interfejsu użytkownika! Wielkie dzięki! –

2

Jeśli używasz await, typem zwrotu będzie Task<BitmapImage>. Jeśli chcesz móc powiązać swój XAML, musisz zwrócić BitmapImage, a zatem nie można użyć await. Użyj polecenia Task.Result zamiast:

public BitmapImage AlbumSource 
{ 
    get 
    { 
     BitmapImage bmp = new BitmapImage(); 
     bmp.SetSource(AlbumThumbnail.OpenReadAsync().GetResults()); 
     return bmp; 
    } 
} 
+0

Ta metoda rozwiązuje mój problem, choć odpowiedź dkackman dała mi inny wymiar w celu zbadania, dzięki obu! ale musiałem zmienić 'Task.Result' na' Task.GetResults() '... i moje złe na błąd składniowy na' SetSource' (powinien to być 'SetSource()'). –

Powiązane problemy