首页 > 解决方案 > 在 xamarin.forms 中单击按钮调用异步任务

问题描述

我有 xamarin.forms 应用程序包含一个列表视图,它将从 Rest API 加载值。这工作正常。我在列表视图上方有按钮。当我单击按钮时,将再次放置列表视图 API 调用并且列表视图应该更新. 但卡在这个更新部分。我没有使用 MVVM 模式。列表视图列表部分是一个异步任务。我在单击按钮时再次调用异步任务,但应用程序崩溃。是不是因为点击按钮再次调用异步任务?任何帮助表示赞赏。

这是我的代码。

 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) { }
            } 
        }
    }

标签: xamarin.forms

解决方案


在解决问题之前有几件事。你的 async/await 都错了,去看看 Async Programming

Task.Run在不同的线程上运行传递的操作,如果您在此线程上更改 UI 元素,您的应用程序肯定会(相信我的话)崩溃。

如果您想在页面启动时进行异步调用,请使用OnAppearing方法(如果您只想调用一次,请维护一个标志)

不要ItemsSource频繁更改列表视图,只需清除并添加项目即可。

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) { }
        } 
    }
}

推荐阅读