How to trigger event in the end of async procedure

BitSmithy 1,731 Reputation points
2020-05-05T20:32:16.583+00:00

Hello,

I have an async method. If the method do its work it should trigger an event, but not before.

    public async Task HandleProjectItem(Project clickedItem)
    {

//some code

//if code did all his work

        this.DataLoaded?.Invoke(this, EventArgs.Empty);

}

Universal Windows Platform (UWP)
{count} votes

2 answers

Sort by: Most helpful
  1. Xiaodi Yan 876 Reputation points MVP
    2020-05-05T20:59:11.237+00:00

    Hi, not sure what you need to do in this task. Can you use something like this:

    await taskA.ContinueWith( antecedent => Console.WriteLine("Today is {0}.", antecedent.Result) );  
    

    You can get the task result from antecedent and the exceptions from antecedent.Exception if there are any exceptions in the task.

    FYI: https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.continuewith?view=netcore-3.1

    By the way, I think you can just use await keyword here and use try-catch block to wrapper the task. Because if there are any errors before the event trigger, the event trigger won't be executed. eg:

    try  
    {  
        //do some tasks  
        await taskA();  
        await taskB();  
        this.DataLoaded?.Invoke(this, EventArgs.Empty);  
    }  
    catch(Exception ex)  
    {  
        //do something  
    }  
    

    Please correct me if I missed anything.


  2. Peter Fleischer (former MVP) 19,056 Reputation points
    2020-06-05T07:14:00.197+00:00

    Hi, you can build class with event and in this class include HandleProjectItem. Try following demo.

    XAML:

    <Page  
        x:Class="App1.Page08"  
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
        xmlns:local="using:App08"  
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  
        mc:Ignorable="d"  
        Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">  
      <Page.DataContext>  
        <local:ViewModel/>  
      </Page.DataContext>  
      <StackPanel>  
        <Button Content="Start read" Command="{Binding Cmd}"/>  
        <TextBox/>  
        <ListBox ItemsSource="{Binding View}">  
          <ListBox.ItemTemplate>  
            <DataTemplate>  
              <TextBlock Text="{Binding Info}"/>  
            </DataTemplate>  
          </ListBox.ItemTemplate>  
        </ListBox>  
      </StackPanel>  
    </Page>  
    

    And classes:

    using System;  
    using System.Collections.ObjectModel;  
    using System.ComponentModel;  
    using System.Runtime.CompilerServices;  
    using System.Threading;  
    using System.Threading.Tasks;  
    using System.Windows.Input;  
    using Windows.UI.Xaml.Controls;  
      
    namespace App08  
    {  
      public class ViewModel : INotifyPropertyChanged  
      {  
        ObservableCollection<Project> col;  
        public ObservableCollection<Project> View { get => col; }  
      
        DataModel m;  
      
        public ICommand Cmd  
        {  
          get => new RelayCommand(async (state) =>  
          {  
            if (m == null)  
            {  
              m = new DataModel();  
              m.DataLoaded += M_DataLoaded;  
            }  
            await m.HandleProjectItem(null);  
          });  
        }  
      
        private void M_DataLoaded(object sender, EventArgs e)  
        {  
          col = m.Collection;  
          OnPropertyChanged(nameof(View));  
        }  
      
        public event PropertyChangedEventHandler PropertyChanged;  
        internal void OnPropertyChanged([CallerMemberName] string propName = "") =>  
          PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));  
      }  
    
      public class Project  
      {  
        public string Info { get; set; }  
      }  
    

    9088-x.png

    0 comments No comments