7
votes

i'm new to xamarin.forms development and i'm still having my first steps from the few tutorials that are found on the net. I have an async task that returns the time from date.jsontest.com and i have a timer that decrements a text in a label. i want to put the async task in the timer so that it repeats itself and displays the time on the label however im getting cannot convert async lamba to func

here's my code please help me, thanks

static async Task<string> RequestTimeAsync()
    {
        using (var client = new HttpClient())
        {
            var jsonString = await client.GetStringAsync("http://date.jsontest.com/");
            var jsonObject = JObject.Parse(jsonString);
            return jsonObject["time"].Value<string>();
        }
    }


 protected override async void OnAppearing()
    {
        base.OnAppearing();

        timeLabel.Text = await RequestTimeAsync();

        Device.StartTimer(TimeSpan.FromSeconds(1), () => { // i want the taks to be put 
//here so that it gets repeated
            var number = float.Parse(button.Text) - 1;
            button.Text = number.ToString();
            return number > 0;
        });

    }

Reloading the Content Page in the timer would do the trick, so if anybody can please help me it would be appreciated

4
Put the async word in front of your lambda, like this Device.StartTimer(TimeSpan.FromSeconds(1), async () => { then you can use the await inside your function.Gerald Versluis
it gave me error: not all code paths return lambda expression of type func<bool>eshteghel company

4 Answers

16
votes

You just need to wrap the async method call in a Task.Run(), for example:

Device.StartTimer(TimeSpan.FromSeconds(1), () =>
{
  Task.Run(async () =>
  {
    var time = await RequestTimeAsync();
    // do something with time...
  });
  return true;
});
-1
votes

A simple clock demonstrates a one second timer action:

       Device.StartTimer(TimeSpan.FromSeconds(1), doitt);
        bool doitt()
        {
            label1.Text = DateTime.Now.ToString("h:mm:ss");
            return true;
        }
-1
votes

or you can try this:

static async Task<string> RequestTimeAsync()
{
    using (var client = new HttpClient())
    {
        var jsonString = await client.GetStringAsync("http://date.jsontest.com/");
        var jsonObject = JObject.Parse(jsonString);
        return jsonObject["time"].Value<string>();
    }
}


protected override async void OnAppearing()
{
    base.OnAppearing();

    var Text = await RequestTimeAsync();

    Device.StartTimer(TimeSpan.FromSeconds(1), () => { 
        // i want the taks to be put 
        //here so that it gets repeated
        var jsonDateTsk = RequestTimeAsync();
        jsonDateTsk.Wait();
        var jsonTime = jsonDateTsk.Result;
        var number = float.Parse(Text) - 1;
        var btnText = $"{number}";
        return number > 0;
    });
}
-2
votes

Solved

as simple as that

 private async void ContinuousWebRequest()
    {
        while (_keepPolling)
        {
            timeLabel.Text = "call: "+counter+" "+ await RequestTimeAsync()+Environment.NewLine;
            // Update the UI (because of async/await magic, this is still in the UI thread!)
            if (_keepPolling)
            {
                await Task.Delay(TimeSpan.FromSeconds(5));
            }
        }
    }

    static async Task<string> RequestTimeAsync()
    {
        using (var client = new HttpClient())
        {
            var jsonString = await client.GetStringAsync("http://date.jsontest.com/");
            var jsonObject = JObject.Parse(jsonString);
            TimePage.counter++;
            return jsonObject["time"].Value<string>();
        }

    }