【问题标题】:Making API call every 5 seconds in C#在 C# 中每 5 秒调用一次 API
【发布时间】:2019-04-21 18:44:57
【问题描述】:

我正在尝试在 Xamarin Forms 平台上开发移动应用程序。我从 API 获取数据。API 调用仅在应用程序打开时发生一次。我在 ListView 中列出团队之间的实时比分。例如现在第 25 场比赛的分钟。我正在等待 2 分钟,但没有任何改变。我的 ListView 上的分钟是相同的。当我关闭并再次打开应用程序时,分钟正在改变。我只想每 5 秒调用一次以刷新数据而不关闭应用程序。 这是我的代码。

public List<liveScoreData>liveScore() 
    {
        var result = new List<liveScoreData>();
        try
        {

            Guid guidSifre = Guid.NewGuid();
            string guid = guidSifre.ToString();
            string result = CreateMD5forChecksum(guid);

            using (var client = new WebClient())
            {
                var values = new NameValueCollection();
                values["result"] = result;
                values["guid"] = guid;

                var response = client.UploadValues("http://abcd.com/admin/LiveScore", values);

                var responseString = Encoding.Default.GetString(response);


                var responseResult = JsonConvert.DeserializeObject(responseString);
                result = JsonConvert.DeserializeObject<List<liveScoreData>>(responseResult.ToString());

                Mehmet.liveScoreDataList = result;

            }
        }
        catch (Exception ex)
        {
            var exc = ex;
        }

        return result;

    }

【问题讨论】:

  • 为什么会得到一个字符串,反序列化为对象,再转回字符串,然后再反序列化?

标签: c# api xamarin call


【解决方案1】:

你可以做的是实现我的特殊 PollingTimer.cs 类:

using System;
using System.Threading;
using Xamarin.Forms;

namespace AppNamespace.Helpers
{
    /// <summary>
    /// This timer is used to poll the middleware for new information.
    /// </summary>
    public class PollingTimer
    {
        private readonly TimeSpan timespan;
        private readonly Action callback;

        private CancellationTokenSource cancellation;

        /// <summary>
        /// Initializes a new instance of the <see cref="T:CryptoTracker.Helpers.PollingTimer"/> class.
        /// </summary>
        /// <param name="timespan">The amount of time between each call</param>
        /// <param name="callback">The callback procedure.</param>
        public PollingTimer(TimeSpan timespan, Action callback)
        {
            this.timespan = timespan;
            this.callback = callback;
            this.cancellation = new CancellationTokenSource();
        }

        /// <summary>
        /// Starts the timer.
        /// </summary>
        public void Start()
        {
            CancellationTokenSource cts = this.cancellation; // safe copy
            Device.StartTimer(this.timespan,
                () => {
                    if (cts.IsCancellationRequested) return false;
                    this.callback.Invoke();
                    return true; // or true for periodic behavior
            });
        }

        /// <summary>
        /// Stops the timer.
        /// </summary>
        public void Stop()
        {
            Interlocked.Exchange(ref this.cancellation, new CancellationTokenSource()).Cancel();
        }
    }
}

然后你可以在你想要每 5 秒调用一次的页面中执行以下操作,在它末尾的构造函数中你可以编写这行代码:

timer = new PollingTimer(TimeSpan.FromSeconds(5), liveScore);

这将每 5 秒运行一次您的方法。要使您的方法与 pollingtimer 一起使用,您必须将方法编辑为 void 并将值返回给全局变量,如下所示:

//Make a global variable for your method to access
  List<liveScoreData> globalLiveScore = new List<liveScoreData>();

      public void liveScore() 
        {
            var result = new List<liveScoreData>();
            try
            {

                Guid guidSifre = Guid.NewGuid();
                string guid = guidSifre.ToString();
                string result = CreateMD5forChecksum(guid);



                using (var client = new WebClient())
                {
                    var values = new NameValueCollection();
                    values["result"] = result;
                    values["guid"] = guid;



                    var response = client.UploadValues("http://abcd.com/admin/LiveScore", values);

                    var responseString = Encoding.Default.GetString(response);



                    var responseResult = JsonConvert.DeserializeObject(responseString);
                    result = JsonConvert.DeserializeObject<List<liveScoreData>>(responseResult.ToString());



                    Mehmet.liveScoreDataList = result;


                }
            }
            catch (Exception ex)
            {
                var exc = ex;
            }


            globalLiveScore = result;



        }

然后您可以从那里通过其他方法检查您的实时比分数据。然后在你的 OnAppearing 方法中你可以运行

timer.Start();

在你的 OnDisappearing 方法中你可以运行

timer.Stop();

试一试,看看是否可以将它放在更好的地方以获得最佳性能等。

【讨论】:

  • 你在这里失去了我的支持:...you must edit your method to a void and return the value to a global variable...。您可以通过将PollingTimer 设为通用,表示其轮询对象的返回类型,并提供一个方法来调用每次轮询的结果,从而极大地改进您的PollingTimer
【解决方案2】:

您可以使用System.Threading.Timer 对象

然后像这样简单地初始化它

`System.Threading.Timer myTimer = new System.Threading.Timer((e) =>
{
    liveScore(); //your function call
}, null, 
TimeSpan.FromSeconds(0), //start immediately
TimeSpan.FromSeconds(5)); //execute every 5 secs`

【讨论】:

  • 谢谢你的回答,但我试过了,没用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-17
  • 1970-01-01
  • 1970-01-01
  • 2023-03-26
  • 2019-02-26
相关资源
最近更新 更多