0
votes

I developed an app with xamarin forms. when I keep the app running on the background for a long time(2-3 hours), the application is going to a state where it can't make any rest calls. it throws an "object reference not set to an instance of an object" error when I try to create the httpClient.

here is the code,

var client = new HttpClient(new NativeMessageHandler());

here is an execution of one of my service calls,

  1. have declared a generic method to take care of service calls. so i'm calling that method with var response = await Session.Instance.LoadList<Entity>();

2.it triggers this

public Task<GetListResponse<T>> LoadList<T>()
    {
        return LoadList<T>(null);
    }

3.then,

async public Task<GetListResponse<T>> LoadList<T>(GetListRequest request)
    {
        var typeName = typeof(T).Name;

        if (request == null)
        {
            request = new GetListRequest() { Index = 0 };
        }

        var response = await Request<GetListResponse<T>>(string.Format("{0}/list", typeName.ToLower()), Newtonsoft.Json.JsonConvert.SerializeObject(request));

        return response;
    }
  1. and finally here is the couple of methods that takes care of the api call,

    async public Task<T> Request<T>(string subUrl, string content) where T : ApiResponse
    {
        if (content == null)
        {
            System.Diagnostics.Debug.WriteLine("GET. " + subUrl);
            return await Request<T>(subUrl);
        }
        else
        {
            System.Diagnostics.Debug.WriteLine("POST. {0}, Content: {1}", subUrl, content);
            return await Request<T>(subUrl, new StringContent(content, UTF8Encoding.UTF8, "application/json"));
        }
    }
    

Request() implimentation,

async public Task<T> Request<T>(string subUrl, HttpContent content = null, int transientRetryCount = 5) where T : ApiResponse'
    {
        try
        {
            HttpResponseMessage response = null;

            using (var client = CreateClient())
            {
                if (content == null)
                    response = await client.GetAsync(Session.Instance.m_url + string.Format("/api/{0}", subUrl));
                else
                    response = await client.PostAsync(Session.Instance.m_url + string.Format("/api/{0}", subUrl), content);
            }

            var responseContent = string.Empty;
            if (response.Content != null)
                responseContent = await response.Content.ReadAsStringAsync();

            if (response.StatusCode != System.Net.HttpStatusCode.OK)
            {
                System.Diagnostics.Debug.WriteLine("Response. {0}, Content: {1}", response.StatusCode, responseContent);

                if ((response.StatusCode == System.Net.HttpStatusCode.BadGateway ||
                    response.StatusCode == System.Net.HttpStatusCode.ServiceUnavailable) && transientRetryCount > 0)
                {
                    //retry...this appears to be a transient error
                    return await Request<T>(subUrl, content, transientRetryCount--);
                }

                return null;
            }

I'm not actually doing anything fancy. but just couldn't find where is the issue is:/

enter image description here

1
Can you give us the stack trace of the exception?Rudi Visser
i don't have a way to capture that since this occurs only when the app is runs on the iphone. and it happens at irregular intervals. i'll try to get it up here when it happens again.CoderKK
You could catch the error and write it to a log file that you could recover later. StackTrace is a string property so you shouldn't have much issue doing that.Rudi Visser
i'm not sure where to log it since it's a mobile app.CoderKK
To a file, or send it up to a web service. Anything that would work on a desktop would work here.Rudi Visser

1 Answers

0
votes

Your issue has nothing todo with xamarin forms. My guess is that the garbage collection run through and removed one of the objects you were referencing. But its hard to tell without knowing your app. What platform are you testing? If its android, maybe an service would be more appropriate for your task.