Background Task Running with Async/Await suggested Approach

KathirVelKathirVel USMember ✭✭

Hi ,

Apologies for the same question.

We are working on Xamarin Forms applcation to support mulitiple platforms ( android ,iOS & Windows Phone) .
Top Priority for Android & iOS Platforms.

We are consuming the control binding information from WCF REST Service.

We have referred the below Links and constructed as below.

  1. async_support_overview
  2. backgrounding-with-xamarin-forms

Code:

public async void Login_Click(object parameter)
        {
            try
            {
                bool bool_serviceRunningCompleted = false;
                this.ActivityIndicatorRunning = true;

                await Task.Run(async () =>    // by putting this Task.Run only the Activity Indicator is shown otherwise its not shown.  So we have added this.
                {
                    Parameters[0] = UserName;
                    Parameters[1] = Password;
                    String ServerValue = await App.TodoManager.CheckLogin(Parameters);

                    Parameters[0] = Team;
                    Parameters[1] = Category;
                    TeamMembers = await App.TodoManager.TeamMembers(Parameters); // List<Team> TeamMembers

                    bool_serviceRunningCompleted = true;
                    // Some logical work around for the application 
                });

                if (bool_serviceRunningCompleted == true)
                    this.ActivityIndicatorRunning = false;

            }
            Catch(Exception Ex)
            {
                DisplayAlert("Sample", "Mobile", "OK");
            }
        }

Whether the above mentioned can be used for Async / Await or any other approach needs to be implemented.

Kindly suggest us the Best approach to proceed on this.

Best Regards,
Kathirvelu M

Posts

  • AdamPAdamP AUUniversity ✭✭✭✭✭

    @KathirVel - While I would recommend using MVVM so you don't have to attach yourself to the click, other than that what exactly is your question. It looks like standard long running process where you place an activity indicator to show its doing something.

    Make sure your controls are disabled so they can't press the button numerous times, and also if not implemented at the lower levels, implement a timeout function.

  • KathirVelKathirVel USMember ✭✭
    edited March 2016

    @AdamP - Apologies, Just for reference it mentioned as click in sample.

    Yes, we are using the MVVM Pattern as recommended earlier and we have controlled the Numerous time Click by Login Button Enabled/Disabled property.

    We are calling the WCF REST Service to fetch data from server and this will take several sever calls to load the page controls.

    In Existing Xamarin.Android applcation we used, [onPreExecute ,DoInBackground,OnPostExecute] (https://developer.xamarin.com/api/type/Android.OS.AsyncTask<TParams,TProgress,TResult>/) for long running tasks.

    But in Xamarin.Forms we used the above mentioned async/await method.

    Suggest on which is the best approach to do long running background tasks with Xamarin.Forms?

  • ThomasBurkhartThomasBurkhart DEMember ✭✭✭✭

    @KathirVel async methods with await only keeps your GUI reactive, but does not really create a background task. For really long running things I would stay with Task.Run.

  • KathirVelKathirVel USMember ✭✭

    @ThomasBurkhart , Thanks for the information.

    Team, So we can use the Long Running Tasks in Task.Run as mentioned in the above code part(Login Method)?

    Kindly mention, if approach and code part need changes.

  • Maharshi.5212Maharshi.5212 USMember ✭✭

    You should write ConfigureAwait(false) with your await parameter. This will solve unnecessary problem.

  • KathirVelKathirVel USMember ✭✭

    @Maharshi.5212 , Thanks for your suggestion.

    We have already included that "ConfigureAwait(false)" in Httpclient for checklogin and other methods as well as mentioned in below code.

     public async Task<string> CheckLogin(object[] parameterValues)
                        {
                            try
                            {
                                String[] parameters = new string[2];
                                parameters[0] = "UserName";
                                parameters[1] = "Password";
                                await StringParameterAsync(parameters, parameterValues, "CheckLogin");
                            }
                            catch (Exception ex)  {     }
                            return outputString;
                        }
    
                  public async Task<String> StringParameterAsync(string[] parameters, object[] parameterValues, string functionName )
                        {
                            try
                            {
                                outputString = string.Empty;
                                System.Net.Http.HttpResponseMessage response;
                                httpClient = new HttpClient();
                                var obj = new JObject();
                                for (int i = 0; i < parameters.Length; i++)
                                {
                                    obj[parameters[i]] = parameterValues[i] + "";
                                }    
                                string s = obj.ToString();    
                                var json_object = JsonConvert.SerializeObject(s);                  
                                url = applicationServiceURL + "/" + functionName;
                                response = httpClient.PostAsync(new Uri(url), new StringContent(s, Encoding.UTF8, "application/json")).Result;
                                using (var responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
                                using (var streamReader = new StreamReader(responseStream))
                                {
                                    string getstring = streamReader.ReadToEnd().ToString();
                                    outputString = (String)Newtonsoft.Json.JsonConvert.DeserializeObject(getstring, typeof(String));
                                }
                            }
    
                            catch (Exception ex)
                            {
                                return throw ex.Message.ToString();
                            }               
                            return outputString;
                        }           
    

    Do we need to include the same in View Model too?

      await Task.Run(async () =>
                            {
                                // Login 
                                // ..... other functions 
    
                            }).ConfigureAwait(false); //Here we need to include?
    

    Thank you very much for your support and guidance.

  • AlmaJensen.9398AlmaJensen.9398 USMember ✭✭✭

    I would seriously suggest checking out the pattern described here. I used it recently and it was pretty easy to understand and implement.

    http://arteksoftware.com/backgrounding-with-xamarin-forms/

  • KathirVelKathirVel USMember ✭✭
    edited March 2016

    @AlmaJensen.9398 , Yes we gone through this link already and its platform specific work around in long running tasks.

    We were trying to achieve the same from Portable (Core) project . if not possible with Xamarin.Forms Core project then we will use the above approach.

    Team, Kindly suggest on the approach to proceed.

  • AlmaJensen.9398AlmaJensen.9398 USMember ✭✭✭

    There are a couple of things I guess you can look at. If you only want Backgrounding to work while your app is running check out the BackgroundWorker in C#.

    If you want Backgrounding to happen while your app isn't on the screen however you will have to do platform specific work. If you are crafty enough I think you might be able to pull it off using the Dependency Service. A quote from the afore mentioned article I think sums it up pretty well. Also check out the Backgrounding articles on this site too.

    One of the most common questions we hear is “How can we run these background tasks in a Xamarin.Forms app?” One of the best features of the Xamarin platform, and Xamarin.Forms specifically, is the ability to share large chunks of our code across platforms. This is often true in the case of background tasks as well. The function that we want to execute, such as saving data or calling a web service, is going to be the same on both iOS and Android. Unfortunately, the way that these two platforms have evolved to handle executing background code is completely different. As such, there is no way that we can abstract the backgrounding feature into the Xamarin.Forms library. Instead, we going to continue to rely on the native APIs to execute our shared background task.

  • AdamPAdamP AUUniversity ✭✭✭✭✭

    @KathirVel - what is the hesitation on using Platform specific code with your Xamarin Forms project? It is a common thing to do on many projects.

    using Task.Run will put your code on a background thread but if your application is backgrounded, so are your threads.

  • Vikas.0825Vikas.0825 USMember ✭✭
    edited July 2016

    @AlmaJensen.9398 , @KathirVel @AdamP , thanks for nice explanation.

    I got confused which i should go for
    1) http://arteksoftware.com/backgrounding-with-xamarin-forms/
    OR
    2.1) https://developer.xamarin.com/guides/ios/application_fundamentals/backgrounding/part_3_ios_backgrounding_techniques/ios_backgrounding_with_tasks/#background_transfers
    2.2) https://developer.xamarin.com/guides/android/application_fundamentals/backgrounding/part_2_android_services/

    As i am not understanding at all,
    @AlmaJensen.9398, Can't i run the task as in 1 method infinite way.

    I have a method which i have to call periodically,
    Can someone provide a sample, it going over my head.

    Thanks

  • Vikas.0825Vikas.0825 USMember ✭✭
    edited July 2016

    @AlmaJensen.9398 , I found a sample code from Githib,
    https://github.com/RobGibbens/XamarinFormsBackgrounding

    Please help me in getting it done. I really not into mobile development in detail before. So i am clueless about which way i should choice for periodic task execution i.e after every 15 min.i want to execute the particular task in Background . Thanks

  • Vikas.0825Vikas.0825 USMember ✭✭

    I was reading the arteksoftware. I found below descrition

    **Start task in iOS

    In the AppDelegate.cs file in the iOS project, we will use Messaging Center to subscribe to the Start and Stop messages. For convenience, I've wrapped the iOS apis in another class named iOSLongRunningTaskExample. The important methods here for iOS are UIApplication.SharedApplication.BeginBackgroundTask ("LongRunningTask", OnExpiration) and UIApplication.SharedApplication.EndBackgroundTask (taskId). These are the methods that tell iOS that we'll be running code in the background and to not terminate our app. As you look at the code in the _iOSLongRunningTaskExample class, pay attention to the fact that it's focused on the code needed to run code in the background on iOS. All of the actual logic, our wonderful infinite loop in this case, is still shared between platforms.**

    Cant i keep my task running even though the app got terminate. Please reply to my query , if any have solution to it.

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    @Vikas.0825 I have this sample, hope it helps https://github.com/acaliaro/TestThread

  • Vikas.0825Vikas.0825 USMember ✭✭
    edited July 2016

    @AlessandroCaliaro , Will it run even if app got terminated

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    No, when App is in background the sample stop the thread (as you can see in OnSleep). You can try to remove the "Cancel" in OnSleep... never tried...

  • Vikas.0825Vikas.0825 USMember ✭✭

    @AlessandroCaliaro , I will try and let you know.

Sign In or Register to comment.