Forum Xamarin Xamarin.Forms

async function blocks the UI

VuyiswaMasekoVuyiswaMaseko USMember ✭✭✭
edited September 15 in Xamarin.Forms

Good Day

i have a function in my datalayer defined like this

public  async   Task<List<PROFILES>>  GetPossibleDates_Profiles(int userid)
        {
            con = new SqlConnection(strCon);
            cmd = new SqlCommand();
            cmd.CommandText = "dbo.spx_GetProfiles";
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.Add("@USER_ID", SqlDbType.Int).Value = userid;
             cmd.Connection = con;cmd.CommandTimeout = 0;
            da = new SqlDataAdapter();
            da.SelectCommand = cmd;
            DataTable dt = new DataTable();
            List<PROFILES> m_List = new List<PROFILES>();
            try
            {

                con.Open();
                    da.Fill(dt);
                    if (dt.Rows.Count > 0)
                    {
                        for (int i = 0; i < dt.Rows.Count; i++)
                        {
                            PROFILESm = new PROFILES();

                            if (dt.Rows[i]["USER_ID"] != DBNull.Value)
                                m.USER_ID = Convert.ToInt32(dt.Rows[i]["USER_ID"]);

                            if (dt.Rows[i]["AGE"] != DBNull.Value)
                                m.AGE = Convert.ToInt32(dt.Rows[i]["AGE"]); 
                            m_List.Add(m);
                        }
                    } 
            }
            catch (SqlException ex)
            {
                throw ex;
            }
            finally
            {
                con.Close();
            }
            return m_List;
        }

in my Xamarin form i have a method define like this

private async Task InitializeProfiles()
        {
            Datalayer obj = new  Datalayer(); 
            try
            { 
                            Profiles = await obj.GetPossibleDates_Profiles(m_userid);

                            Device.BeginInvokeOnMainThread(() =>
                            {
                                SwipeCardView.ItemsSource = Profiles;
                                SwipeCardView.BindingContext = Profiles;
                            });   
            }
            catch (Exception ex)
            { 
                    DependencyService.Get<IServiceImei>().ShowToast(ex.Message); 
            }
            finally
            {
                obj = null; 
            }

        }

and i call this function which load data and bind a Swipecard like this

        public MatchesView()
    {
            InitializeComponent(); 
                   InitializeProfiles();
        }

So my problem is that this line of code inside the InitializeProfiles() blocks the UI , i want it to go get data and continue with other stuff and when its done , it can bind the data on the control , but when i put a breakpoint, i realized that it waits for Datalayer function to complete before it can continue.

****
     Profiles = await obj.GetPossibleDates_Profiles(m_userid);****

Best Answer

Answers

  • JohnHardmanJohnHardman GBUniversity mod
    edited September 16

    @VuyiswaMaseko

    The GetPossibleDates_Profiles method contains only synchronous operations, so it will keep busy whichever thread it is called on. In its current form, there is no point in it returning Task or being marked as async. I suspect that Visual Studio, through Intellisense and/or a warning, will report this.

    There are various options as to how to change this. For instance, you could change the Sqlite operations to async forms that you then await (in which case, you would keep the method returning Task and being marked as async). Alternatively, you could use Task.Run (as per the post by @AlessandroCaliaro ) (although, in that case, check whether your ShowToast also needs to be wrapped in Device.BeginInvokeOnMainThread).

  • VuyiswaMasekoVuyiswaMaseko USMember ✭✭✭

    Thank you , @AlessandroCaliaro solution worked

Sign In or Register to comment.