Anand
Anand

Reputation: 1959

Calling Async task in button click in xamarin.forms

I have xamarin.forms app contains a listview which will load values from Rest API.Which is working fine.I have button just above the listview.When I click on the button, the listview API call will be placed again and the listview should update. But stuck at this update part.I am not using MVVM pattern.The listview listing portion is an async Task.I am calling the async task again when the button click, but App gets crash. Is it due to calling the async task again from button click? Any help is appreciated.

Here is My code.

 namespace app
    {
        public partial class List : ContentPage
        {   
            PendingWeekRange pendingWeekRange = new PendingWeekRange();
            public TimeSheetList()
            {
                InitializeComponent();        
                Task.Run(async () =>
                {
                    await LoadScreenItems();
                });           
            }    
            async Task LoadScreenItems()
            {
               await Task.Run(async () => {               
                    try
                    {                 
                          // Doing some stuff

                            await loadTimeSheetList();               
                    }
                    catch (Exception)
                    {

                    }
                });
            }  
            async Task loadTimeSheetList()
            {
                await Task.Run(() => {  +  string postdataForPendingList = "{\"date\":\"" + "1" + "\"}";
                APICall callForAPICallResult = new APICall("/API/ListMobile/ListForApproval", postdataForList, loadingIndicator);       
                    try
                    {                                        
                        List<ListData> resultObjForPendingTimeSheetList = callForAPICallResult<List<ListData>>();
                        if (resultObjForPendingTimeSheetList != null)
                        {

                            TimesheetList.ItemsSource = resultObjForPendingTimeSheetList;
                            screenStackLayout.VerticalOptions = LayoutOptions.FillAndExpand;
                            TimesheetList.IsVisible = true;
                        }
                        else
                        {

                        }
                    }
                    catch (Exception)
                    {                    
                    }
                });          
            }
         async   void Button_Tapped(object sender, EventArgs e)
            {
                try
                {            
                      // Calling my listview again. After calling app gets crash                
                  Task.Run(async () => await loadTimeSheetList());                           
                }
                catch (Exception ex) { }
            } 
        }
    }

Upvotes: 0

Views: 2492

Answers (2)

Ranga
Ranga

Reputation: 1108

A few things before getting to the problem. You've got async/await all wrong, go though Async Programming

Task.Run runs the passed action on a different thread, if you make changes to UI elements on this thread, your app will definitely(take my word) crash.

If you want to make async call at page launch, make use of OnAppearing method (if you only want to call once, maintain a flag)

Do not change the ItemsSource of a list view frequently, just clear and add items to it.

namespace app
{
    public partial class List : ContentPage
    {   
        PendingWeekRange pendingWeekRange = new PendingWeekRange();

        private ObservableCollection<ListData> TimesheetObservableCollection = new ObservableCollection<ListData>();
        public TimeSheetList()
        {
            InitializeComponent();          
            TimesheetList.ItemsSource = TimesheetObservableCollection;
        }
        protected override async OnAppearing()
        {
            // flag for first launch?
            await LoadScreenItems();

        }
        async Task LoadScreenItems()
        {     
            try
            {                 
                    // Doing some stuff
                    TimesheetObservableCollection.Clear();
                    TimesheetObservableCollection.AddRange(await GetTimeSheetList());
            }
            catch (Exception)
            {
                //handle exception
            }
        }  
        async Task<List<ListData>> GetTimeSheetList()
        {
            string postdataForPendingList = "{\"date\":\"" + "1" + "\"}";
            APICall callForAPICallResult = new APICall("/API/ListMobile/ListForApproval", postdataForList, loadingIndicator);       
            try
            {                                        
                return callForAPICallResult<List<ListData>>();
            }
            catch (Exception) 
            { 
                // handle exception
            }        
        }
        async void Button_Tapped(object sender, EventArgs e)
        {
            try
            {
                // Calling my listview again. After calling app gets crash                
                TimesheetObservableCollection.Clear();
                TimesheetObservableCollection.AddRange(await GetTimeSheetList());
            }
            catch (Exception ex) { }
        } 
    }
}

Upvotes: 1

Krunal Bagadia
Krunal Bagadia

Reputation: 419

@Androdevil,

Update your loadTimeSheetList with this,

async Task loadTimeSheetList()
    {

            try
            {            
                // I am calling my API for Listview here.            
                List<TimeSheetListData> resultObjForPendingTimeSheetList = await callForPendingTimeSheetList.APICallResult<List<TimeSheetListData>>();
                if (resultObjForPendingTimeSheetList != null)
                {

                    TimesheetList.ItemsSource = resultObjForPendingTimeSheetList;
                    screenStackLayout.VerticalOptions = LayoutOptions.FillAndExpand;
                    TimesheetList.IsVisible = true;
                }
                else
                {

                }
            }
            catch (Exception)
            {                    
            }

    }

Upvotes: 0

Related Questions