如果已经是 运行 计时器,如何解决不需要的 webrequest 调用?

How to solve undesirable webrequest call if it is already running with timer?

我有一个计时器,因为

 public static System.Timers.Timer timer_get = new System.Timers.Timer();
 timer_get.Elapsed += new ElapsedEventHandler(Get_OnTimedEvent);
 timer_get.Interval = 1000;
 timer_get.Enabled = true;

正在打这个方法

public static void GetListFromDb()
        {
            try
            {
              DataTable dt = new DataTable();
                //..here is i am filling datatable
                Parallel.ForEach(dt.AsEnumerable(), row => {
                    GetDataFromApi(row);
                });
            }
            catch (Exception e)
            {
                //..
            }
        }

每一行都有不相关的 webrequest 个元素(url、类型等)。我同时发送webrequest方法

问题是 webrequest 比分辨率为 1000 毫秒以上的计时器时钟花费更多的时间。 运行 请求经常遇到这个问题,我不知道如何解决。有没有办法检测一个方法是否已经是运行一个特定的参数?

实现此目的的一种方法是将计时器的自动重置 属性 设置为 false。这将确保您的回调不会被重新输入,直到您手动告诉计时器再次触发。这种方法会很有效,因为 Parallel.ForEach 在循环完成之前不会 return。这是使用您的代码的示例:

namespace Test
{
    class Program
    {
        public static System.Timers.Timer timer_get = new System.Timers.Timer();

        public static void Main()
        {
            timer_get.Elapsed += new ElapsedEventHandler(Get_OnTimedEvent);
            timer_get.Interval = 1000;
            timer_get.AutoReset = false;
            timer_get.Enabled = true;

            Console.WriteLine("Any Key to Exit");
            Console.ReadLine();

        }

        private static void Get_OnTimedEvent(object sender, ElapsedEventArgs e)
        {
            try
            {
                GetListFromDb();
            }
            finally
            {
                timer_get.Start();
            }
        }

        public static void GetListFromDb()
        {
            try
            {
                Thread.Sleep(5000);
                //..
                //..
                //..
            }
            catch (Exception e)
            {
                //..
            }
        }
    }
}

如果您可以通过某个键识别每个请求,则可以管理 "running" 个请求的字典

public static System.Timers.Timer timer_get = new System.Timers.Timer();
private static ConcurrentDictionary<string, bool> _runningRequests = new ConcurrentDictionary<string, bool>();

然后

    static void GetDataFromApi(DataRow row)
    {
        var requestKey = (string)row["Url"];

        if (_runningRequests.TryAdd(requestKey, true))
        {
            try
            {
                //send web request
            }
            finally
            {
                bool alreadyRunning;
                _runningRequests.TryRemove(requestKey, out alreadyRunning);
            }
        }
    }