Search code examples
c#uwpwin-universal-app

Async StackOverflowException


Below I have a line of code that calls SearchAlbums(text). By removing this line I no longer get StackOverflowException so I believe this is the line that gives me the trouble.

    public ObservableCollection<AlbumView> Albums = new ObservableCollection<AlbumView>();

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        base.OnNavigatedTo(e);
        if (e.Parameter is string text)
        {
            // User Search
            MainPage.Instance.SetHeaderText(GetSearchHeader(text, MainPage.Instance.IsMinimal));
            History.Push(text);
            SearchArtists(text);
            SearchAlbums(text);
            SearchSongs(text);
            SearchPlaylists(text);
        }
        else
        {
            // Back to Search Page
            MainPage.Instance.SetHeaderText(GetSearchHeader(History.Pop(), MainPage.Instance.IsMinimal));
        }
    }

    public void SearchAlbums(string text)
    {
        Albums.Clear();
        foreach (var group in MusicLibraryPage.AllSongs.Where((m) => IsTargetAlbum(m, text)).GroupBy((m) => m.Album))
        {
            Music music = group.ElementAt(0);
            Albums.Add(new AlbumView(music.Album, music.Artist, group.OrderBy((m) => m.Name).ThenBy((m) => m.Artist)));
        }
    }

Therefore, I set a breakpoint in this function and I was actually able to run this function without an exception. The StackOverflowException occurred after OnNavigatedTo has been executed.

I think the constructor of AlbumView might have something to do with it:

    public AlbumView(string name, string artist, IEnumerable<Music> songs)
    {
        Name = name;
        Artist = artist;
        Songs = new ObservableCollection<Music>(songs);
        FindThumbnail();
    }
    public async void FindThumbnail()
    {
        foreach (var music in Songs)
            if ((Cover = await Helper.GetThumbnailAsync(music, false)) != null)
                break;
        if (Cover == null) Cover = Helper.DefaultAlbumCover;
    }

But I also use this constructor elsewhere in another page, and that page displayed perfectly.

The first piece of code posted above is in this page. And the exception occurs when there is a match album.

I don't know how to fix it. I can only guess it might be the issue of async operation. Thanks in advance!


Solution

  • I tested your code. Your problem is not in code-behind, but on the control.

    For instances that have an asynchronous, use Binding instead of x:Bind for the binding of the instance. Because Binding is a runtime binding, and x:Bind is a compile-time binding.

    change your code to this:

    SearchPage.xaml

    ...
    <controls:Carousel.ItemTemplate>
        <DataTemplate x:DataType="data:AlbumView">
            <local:GridAlbumControl DataContext="{Binding}" />
        </DataTemplate>
    </controls:Carousel.ItemTemplate>
    ...
    

    Best regards.