question

AbrahamJohn-8020 avatar image
0 Votes"
AbrahamJohn-8020 asked CherryBu-MSFT commented

Cancel current Task.Delay

I'm performing swipe to delete items from a list named mylist. After an item is deleted I want to show an "UNDO" button for 10 seconds.

Here are my codes.

xaml code:

 <CollectionView x:Name="list" VerticalOptions="Center">
     <CollectionView.ItemTemplate>
         <DataTemplate>
              <SwipeView>
                   <SwipeView.LeftItems>
                       <SwipeItems Mode="Execute" SwipeBehaviorOnInvoked="Close">
                           <SwipeItem Text="Delete" BackgroundColor="Red" Invoked="Delete_Invoked"/>
                       </SwipeItems>
                    </SwipeView.LeftItems>
                    <Label Text="{Binding .}" TextColor="Black" FontSize="10" VerticalTextAlignment="Center" HorizontalTextAlignment="Start"/>
               </SwipeView>
          </DataTemplate>
      </CollectionView.ItemTemplate>
 </CollectionView>
    
 <AbsoluteLayout x:Name="undo_msg" IsVisible="false">
      <ContentView x:Name="undo_item" AbsoluteLayout.LayoutBounds="0,0,1,1" HeightRequest="50" AbsoluteLayout.LayoutFlags="All"  BackgroundColor="#f1f1f1" Padding="0,5,5,0">
           <Grid VerticalOptions="Center" HorizontalOptions="Center" Padding="5,0,5,0">
               <Grid.RowDefinitions>
                   <RowDefinition Height="*"/>
               </Grid.RowDefinitions>
               <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="80"/>
               </Grid.ColumnDefinitions>
               <Label x:Name="undo_label" Grid.Row="0" Grid.Column="0" TextColor="Black" FontSize="16" LineBreakMode="TailTruncation" VerticalTextAlignment="Center" HorizontalTextAlignment="Start"/>
               <Button Grid.Row="0" Grid.Column="1" Text="UNDO" TextColor="Blue" FontAttributes="Bold" FontSize="15"VerticalOptions="Center" HorizontalOptions="End" BorderWidth="0" BackgroundColor="Transparent"/>
          </Grid>
      </ContentView>
 </AbsoluteLayout>


xaml.cs

 private async void Delete_Invoked(object sender, EventArgs e)
 {
     SwipeItem itemswipe = sender as SwipeItem;
     string item= itemswipe.BindingContext as string;
     mylist.Remove(item);
     undo_label.Text = "Deleted \"" + item+ "\"";
     undo_msg.IsVisible = true;
     await Task.Delay(10000);
     undo_msg.IsVisible = false;
 }

 protected override void OnAppearing()
 {
     base.OnAppearing();
     list.ItemsSource = mylist;
 }

If i delete an item from list and after 5 sec if I deletes another item, i want the current Task.Delay to be cancelled and start a new one. I heard this can done using cancellation token. But i don't know!

Help would be appreciated.




dotnet-xamarin
5 |1600 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.

1 Answer

CherryBu-MSFT avatar image
0 Votes"
CherryBu-MSFT answered CherryBu-MSFT commented

Hello,

Welcome to our Microsoft Q&A platform!

If i delete an item from list and after 5 sec if I deletes another item, i want the current Task.Delay to be cancelled and start a new one. I heard this can done using cancellation token. But i don't know!

You can use CancellationTokenSource.Cancel Method to cancel Task and use CancellationToken.ThrowIfCancellationRequested Method to check this token has had cancellation requested.

Please see my following code, I use Stopwatch to count time.

  Stopwatch stopWatch;
         double count;
         private async void Delete_Invoked(object sender, EventArgs e)
         {
             var tokenSource = new CancellationTokenSource();
    
             SwipeItem itemswipe = sender as SwipeItem;
             string item = itemswipe.BindingContext as string;
             mylist.Remove(item);
    
             if(stopWatch!=null)
             {
                 count = stopWatch.ElapsedMilliseconds;
                 if (count < 100000)
                 {
                     tokenSource.Cancel();
                 }
             }
                       
              
             undo_label.Text = "Deleted \"" + item + "\"";
             undo_msg.IsVisible = true;
    
             stopWatch = new Stopwatch();
             stopWatch.Start();
    
             await Task.Run(() => TaskDelayTest(tokenSource.Token));
    
             undo_msg.IsVisible = false;
         }
    
         public async Task TaskDelayTest(CancellationToken token)
         {
                
               
             if (!token.IsCancellationRequested)
             {
                 Console.WriteLine("End " + Task.CurrentId);
             }
             else
             {
                 Console.WriteLine("Cancelled " + Task.CurrentId);
                   
             }
             await Task.Delay(10000);
    
         }

Best Regards,

Cherry Bu


If the response is helpful, please click "Accept Answer" and upvote it.

Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.




· 6
5 |1600 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 got Java.Lang.RuntimeException.

91152-screenshot-103.png


0 Votes 0 ·
screenshot-103.png (23.0 KiB)

Hi @AbrahamJohn-8020 According to your error message, I guess that you want to call Toast, you can not show a Toast on non-UI thread, try this code Device.BeginInvokeOnMainThread(() => { undo_msg.IsVisible = false; });


0 Votes 0 ·

@CherryBu-MSFT

I've done that.


But timing problem still exists that if we delete second item after 5s of first item been deleted, Undo is showing only for 5s not cancelling previous delay.


0 Votes 0 ·
Show more comments