C#System.Threading.Timer及其状态对象

时间:2010-04-22 10:36:13

标签: c# .net

我正在编写一个C#程序,它使用System.Threading.Timer在UDP套接字ReceiveAsync调用上超时。

我的程序轮询一个远程设备,发送一个UDP数据包并期待一个回复。

我在一次性模式下使用定时器,每当我想要一个新的超时时间时调用Timer.Change。

对于每次超时的发生,我都希望超时处理程序能够获得不同的信息。

如果我在创建时更改了传递给Timer的对象,那么当处理程序执行时它似乎没有改变。

唯一的方法是破坏计时器并创建一个新计时器吗?

谢谢,

4 个答案:

答案 0 :(得分:1)

您是否传递结构而不是类对象?结构是值类型,您将获得它的第一个版本的副本。由于状态未在回调中被ref传递,因此您所做的更改将会丢失。使用类而不是结构是一个简单的解决方案。

将状态对象存储在您自己的类中是另一种方法。

答案 1 :(得分:0)

您传递的对象可能是一个数组,其中包含您在每次超时时替换的单个元素。

答案 2 :(得分:0)

考虑这个便宜的包装:

sealed class TimerWrapper : IDisposable
{
    readonly Timer timer;

    object State { get; set; }

    public TimerWrapper(TimerCallback callback) 
    {
        timer = new Timer(delegate { callback(State); });
    }

    public void Change(object state, TimeSpan dueTime, TimeSpan period)
    {
        timer.Change(dueTime, period);
        State = state;
    }

    public void Dispose()
    {
        timer.Dispose();
    }
}

请注意,使用上述代码可能会在某些罕见的竞争条件下导致意外行为。

答案 3 :(得分:0)

使用WaitHandle并锁定以同步