创建“一次运行"的最佳方式C#中的延时函数 [英] Best way to create a "run-once" time delayed function in C#

查看:12
本文介绍了创建“一次运行"的最佳方式C#中的延时函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个接受操作和超时的函数,并在超时后执行操作.该功能是非阻塞的.该函数必须是线程安全的.我也非常非常想避免使用 Thread.Sleep().

I am trying to create a function that takes in an Action and a Timeout, and executes the Action after the Timeout. The function is to be non-blocking. The function must be thread safe. I also really, really want to avoid Thread.Sleep().

到目前为止,我能做的最好的是:

So far, the best I can do is this:

long currentKey = 0;
ConcurrentDictionary<long, Timer> timers = new ConcurrentDictionary<long, Timer>();

protected void Execute(Action action, int timeout_ms)
{
    long currentKey = Interlocked.Increment(ref currentKey);
    Timer t = new Timer(
      (key) =>
         {
           action();
           Timer lTimer;
           if(timers.TryRemove((long)key, out lTimer))
           {
               lTimer.Dispose();
           }
         }, currentKey, Timeout.Infinite, Timeout.Infinite
      );

     timers[currentKey] = t;
     t.Change(timeout_ms, Timeout.Infinite);
}

问题是从回调本身调用 Dispose() 不太好.我不确定脱离"结束是否安全,即定时器在其 lambda 执行时被认为是活动的,但即使是这种情况,我也宁愿正确处理它.

The problem is that calling Dispose() from the callback itself cannot be good. I am unsure if it is safe to "fall off" the end, i.e. Timers are considered live while their lambdas are executing, but even if this is the case I'd rather dispose it properly.

延迟触发一次"似乎是一个常见的问题,应该有一种简单的方法可以做到这一点,可能是 System.Threading 中的其他一些库我缺少,但现在我能想到的唯一解决方案是对上述内容的修改,其中有一个间隔运行的专用清理任务.有什么建议吗?

The "fire once with a delay" seems like such a common problem that there should be an easy way to do this, probably some other library in System.Threading I am missing, but right now the only solution I can think of is modification of the above with a dedicated cleanup task running on an interval. Any advice?

推荐答案

我不知道您使用的是哪个版本的 C#.但我认为您可以通过使用 Task 库来实现这一点.然后它看起来像那样.

I don't know which version of C# you are using. But I think you could accomplish this by using the Task library. It would then look something like that.

public class PauseAndExecuter
{
    public async Task Execute(Action action, int timeoutInMilliseconds)
    {
        await Task.Delay(timeoutInMilliseconds);
        action();
    }
}

这篇关于创建“一次运行"的最佳方式C#中的延时函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆