1

Im doing with the activity indicator of the xamarin. I want to stop the indicator after the product is get.

protected override void OnAppearing()
    {
        base.OnAppearing();

        if (!_appeared) // Avoid repeat loding
        {
            activity.IsEnabled = true;
            activity.IsRunning = true;
            activity.IsVisible = true;

            var task = Task.Run(() =>
            {
                ProductViewData productViewData = new ProductViewData();
                products = productViewData.GetProductList("10");
                count = 10;
                productListView.ItemsSource = products;
            });

            task.ContinueWith(t =>
            {
                activity.IsEnabled = false;
                activity.IsRunning = false;
                activity.IsVisible = false;
            });

            _appeared = true;
        }
    }

Thanks for any help.

BlackLotus
  • 496
  • 2
  • 9
  • 24

2 Answers2

3

Code like this is a lot easier with async/await:

protected override async void OnAppearing()
{
    base.OnAppearing();

    if (!_appeared) // Avoid repeat loding
    {
        _appeared = true;
        activity.IsEnabled = true;
        activity.IsRunning = true;
        activity.IsVisible = true;

        var products = await Task.Run(() =>
        {
            ProductViewData productViewData = new ProductViewData();
            return productViewData.GetProductList("10");
        });

        productListView.ItemsSource = products;

        activity.IsEnabled = false;
        activity.IsRunning = false;
        activity.IsVisible = false;
    }
}

Although the code is simple and readable, there's a lot going on behind the scenes, particularly around when this method returns, and what thread the code after the await is run on. It is well worth reading up on this.

canton7
  • 37,633
  • 3
  • 64
  • 77
  • this throw me an error and i dont know what is it. `Unhandled Exception: Android.Util.AndroidRuntimeException: Only the original thread that created a view hierarchy can touch its views. occurred` – BlackLotus Feb 16 '19 at 15:21
  • @Jweiwei ah, you need to move `productListView.ItemsSource = products` out of the `Task.Run`. I'll update my answer. – canton7 Feb 16 '19 at 15:28
  • done. but how it work actually? not really understand await and async =( – BlackLotus Feb 16 '19 at 15:44
1

I guess this is what you need.

var task = Task.Run(delegate { Console.WriteLine("Task started!"); })
           .ContinueWith(delegate { Console.WriteLine("Task continued"); });

Just wrap what you wanna do as functions and call that functions in your task steps. For more information read here.

Edit:

Since an UI operation is the subject of this question, I thought this code from the page I linked would be more useful. This code utilizes UI and background scheduler.

private void Button1_Click(object sender, EventArgs e)  
{  
   var backgroundScheduler = TaskScheduler.Default;  
   var uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();  
   Task.Factory.StartNew(delegate { DoBackgroundComputation(); },  
                         backgroundScheduler).  
   ContinueWith(delegate { UpdateUI(); }, uiScheduler).  
                ContinueWith(delegate { DoAnotherBackgroundComputation(); },  
                             backgroundScheduler).  
                ContinueWith(delegate { UpdateUIAgain(); }, uiScheduler);  
}  
Hasan
  • 1,243
  • 12
  • 27
  • This won't work, as the continuation won't be run on the UI thread – canton7 Feb 16 '19 at 12:23
  • Your code does not even compile! Stop editing things before trying. @canton7 – Hasan Feb 16 '19 at 12:25
  • My bad, `.ContinueWith(t => Console.WriteLine("..."))` would be correct. Nobody uses the anonymous delegate syntax since C# 3 introduced lambdas, though. – canton7 Feb 16 '19 at 12:27
  • No, it would not work as well. Also, editing answers to the question that you also answered does not look ethical. More improtantly, as you can see in the page I linked, microsoft's itself publish code with delegate. I do not think nobody uses them anymore.@canton7 – Hasan Feb 16 '19 at 12:31
  • Yes, it would do the same thing. SO is a Q/A site, and having a range of different high-quality answers is good. I'm not trying to get my answer to "win", I'm trying to improve the site by getting a range of good-quality answers. That includes improving other answers. If your answer took account of dispatching back to the UI thread (e.g. using `TaskScheduler.FromCurrentSynchronizationContext()`), I would upvote it as well. I don't see anything unethical about this approach to improving overall quality. Also, the MSDN examples are often of low quality. – canton7 Feb 16 '19 at 12:35
  • It does not look like you are not trying to 'win' when editing my code with some garbage. Also, in the page I linked there are examples and first of them utilizes TaskScheduler.FromCurrentSynchronizationContext()). I just added a basic code so do not just read the code snippets before judging. @canton7 – Hasan Feb 16 '19 at 12:38
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/188515/discussion-between-canton7-and-hasan). – canton7 Feb 16 '19 at 12:39