question

BitSmithy-4663 avatar image
0 Votes"
BitSmithy-4663 asked ·

How to trigger event in the end of async procedure

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);

}

windows-uwp
· 3
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Does @yanxiaodi 's answer make sense? If it helps you, you could mark it as answer.

0 Votes 0 ·

Have you solved your issue? Please feel free to ask if you still have problems.

0 Votes 0 ·

I explained my problem more precisely. Look at my last comment.

0 Votes 0 ·
yanxiaodi avatar image
0 Votes"
yanxiaodi answered ·

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://docs.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.

· 4 ·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

I am adding data to observable collection in async procedure, so if I Invoke event at the end of the procedure I cant be sure if event will be trigered after all data are added.

I need code which first adds all data in async procedure to ObservableCollection, and next after adding is completed it invokes event.

I am not familiar with async programing, so I dont know how to do it.



public async Task HandleProjectItem(Project clickedItem)
{
//some code

   foreach (var item in filesToOpen)
   {
         //Add data to ObservableCollection

    }

//if all data are added to ObservableCollection, Invoke event, but not before

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

}

0 Votes 0 ·

Hi, thanks for your clarification. For you case I didn't see any async operation? Is it necessary to use async for HandleProjectItem?
If Add data to ObservableCollection action is a sync method, feel free to just use HandleProjectItem method as a sync method.

async won't block the thread for heavy tasks but you only use it for a method which has one or more operations that can be await. If you don't have await in this method, no need to use async for it. FYI: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/

0 Votes 0 ·

This procedure is Async, because first I read data from file (and this needs async and await), and next I put read data to the observable collection. So my code needs four parts

Async procedure()
{
1. Read data from file (this needs awiat, and forces async)
2. Put read data in observable collection
3. wait for reading data to obserwable collectio (I dont know how to do this)
4. Trigger event (but dont trigger it before observable collection is loaded with all the data)

}

0 Votes 0 ·
Show more comments
PeterFleischer-3316 avatar image
0 Votes"
PeterFleischer-3316 answered ·

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



x.png (72.8 KiB)
·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.