【问题标题】:Calling Async task in button click in xamarin.forms在 xamarin.forms 中单击按钮调用异步任务
【发布时间】:2019-11-09 01:52:23
【问题描述】:

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

【问题讨论】:

  • 用这个更新你的代码并检查。 async void Button_Tapped(object sender, EventArgs e) { try { // 再次调用我的列表视图。调用应用程序崩溃后等待 loadTimeSheetList(); } 捕捉(异常前){ } }
  • @KrunalBagadia 嗨,我试过了,还是不行
  • @AndroDevil 你的APICallResult是任务类型方法吗?如果是这样,为什么不直接称它为await callForPendingTimeSheetList.APICallResult&lt;List&lt;TimeSheetListData&gt;&gt;();
  • @LandLu-MSFT Bro 我编辑了我的代码。 “APICALL”是另一个进行 API 调用的类
  • @AndroDevil 仍然无法弄清楚您的 APICall 是什么样的。尝试用 const fake list data 测试一下,还会崩溃吗?

标签: xamarin.forms


【解决方案1】:

在解决问题之前先做几件事。你的 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) { }
        } 
    }
}

【讨论】:

    【解决方案2】:

    @Androdevil,

    用这个更新你的 loadTimeSheetList,

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

    【讨论】:

    • 如果我删除了 Await.Task.Run 那么它将作为 Synchronosly 运行吗?
    • 没有。检查这一行 List resultObjForPendingTimeSheetList = await callForPendingTimeSheetList.APICallResult>();正在等待通话。
    • 它没有解决它兄弟
    猜你喜欢
    • 2016-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-21
    相关资源
    最近更新 更多