Async and await: UI thread is blocked

vinodkumarvinodkumar INMember ✭✭
edited May 2016 in Xamarin.Forms

Hi,

I have this architecture in my project and sometimes UI thread is getting blocked, can someone please explain what is happening with the below code. Thanks

I am making a service call asyncronously from xamarin.forms viewmodel

Following is the flow

View--->ViewModel---ClassA--->ClassB--Make a service call from here

Code

Scenario 1

public partial class HomePage : ContentPage
{
    private HomeVM model;

    public HomePage()
    {
        InitializeComponent();
        model = new HomeVM();
        model.MainText = ReturnBool().Result;
        this.BindingContext = model;
    }
    public async Task<string> ReturnBool()
    {
        IsBusy = true;
        var r = await new WS().ReturnBool();
        IsBusy = false;---------------------------------------Not hitting the breakpoint here
        return r;
    }
}

public interface IWS
{
    Task<string> ReturnBool();
}

public class WS : IWS
{
    public Task<string> ReturnBool()
    {
        return ServiceOperations.ReturnBool();
    }
}

internal class ServiceOperations
{
    public async static Task<string> ReturnBool()
    {
        var uri = new Uri(string.Format("http://testmyapi.azurewebsites.net/", string.Empty)); 
        try
        {
            HttpClient client = new HttpClient();
            client.BaseAddress = uri;
            HttpResponseMessage response = null;
            response = await client.GetAsync("/api/Values/Get");
            if (response.IsSuccessStatusCode)
            {
                var content = await response.Content.ReadAsStringAsync();
                string str = JsonConvert.DeserializeObject<string>(content);
                return str;
            }
            else {
                return null;
            }
        }
        catch (Exception)
        {
            return null;
        }
    }
}

Scenario 2

public partial class HomePage : ContentPage
{
    private HomeVM model;

    public HomePage()
    {
        InitializeComponent();
        model = new HomeVM(); 
        this.BindingContext = model;
    } 
}

public class HomeVM : BaseVM
{
    private string mainText;

    public string MainText
    {
        get { return mainText; }
        set
        {
            mainText = value;
            RaisePropertyChanged("MainText");
        }
    }

    public HomeVM()
    {
        MainText = ReturnBool().Result; 
    }

    public async Task<string> ReturnBool()
    {
        IsBusy = true;
        var r = await new WS().ReturnBool();
        IsBusy = false;---------------------------------------Not hitting the breakpoint here
        return r;
    }
}


public interface IWS
{
    Task<string> ReturnBool();
}

public class WS : IWS
{
    public Task<string> ReturnBool()
    {
        return ServiceOperations.ReturnBool();
    }
}

internal class ServiceOperations
{
    public async static Task<string> ReturnBool()
    {
        var uri = new Uri(string.Format("http://testmyapi.azurewebsites.net/", string.Empty)); 
        try
        {
            HttpClient client = new HttpClient();
            client.BaseAddress = uri;
            HttpResponseMessage response = null;
            response = await client.GetAsync("/api/Values/Get");
            if (response.IsSuccessStatusCode)
            {
                var content = await response.Content.ReadAsStringAsync();
                string str = JsonConvert.DeserializeObject<string>(content);
                return str;
            }
            else {
                return null;
            }
        }
        catch (Exception)
        {
            return null;
        }
    }
}

It would be great if anyone explains why UI thread is getting blocked.

Best Answer

Answers

  • vinodkumarvinodkumar INMember ✭✭

    @johannes Thank you for your answer and it helped me, below code worked.

    public partial class HomePage : ContentPage
    {
    private HomeVM model;

        public HomePage()
        {
            InitializeComponent();
            model = new HomeVM();
            model.ReturnBool();
            this.BindingContext = model; 
        }  
    }
    

    public class HomeVM : BaseVM
    {
    private string mainText;

        public string MainText
        {
            get { return mainText; }
            set
            {
                mainText = value;
                RaisePropertyChanged("MainText");
            }
        }
    
        public HomeVM()
        {            
        }
    
        public async Task<string> ReturnBool()
        {
            IsBusy = true;
            var r = await new WS().ReturnBool();
            MainText = r;
            IsBusy = false;
            return r;
        }
    }
    
Sign In or Register to comment.