如何使用传递给system.threading.timer的状态对象? [英] How do I use the state object passed to a system.threading.timer?
问题描述
我对 System.Threading.Timer
类感到有些困惑。以下代码编译并运行正常:
Hi,
I am a little confused by the System.Threading.Timer
class. The following code compiles and runs fine:
using System;
using System.Threading;
namespace ConsoleApplication1
{
public class Repeater
{
public Repeater( Action<object> callback, object state )
{
// Timer takes a TimerCallback delegate, but this constructor takes an Action<object>. I have
// read the easiest way to 'cast' a delegate is using lambdas. Like this:
TimerCallback tcb = ( s ) => callback( s );
// So now I can construct my Timer.
_timer = new Timer( tcb, state, 0, 5000 );
}
private Timer _timer = null;
}
public class Program
{
static void Main( string[] args )
{
Action<object> callback = MyFunction;
Repeater repeater = new Repeater( callback, _count );
Console.ReadKey();
}
private static void MyFunction( object state )
{
Console.WriteLine( $"event...{(int)state}" );
}
private static int _count = 42;
}
}
每5秒打印一次事件...... 42。 />
当我在计时器
上阅读MSDN文档时(Timer构造函数(TimerCallback,Object,Int64,Int64)(System.Threading)),它表示状态参数是:包含要由回调方法使用的信息的对象。这意味着每次调用时我都可以以某种方式将信息传递给回调函数。所以,在我上面的例子中,我可以找到一种方法让回调打印出42 ... 43 ... 44 ......等等。
是有没有办法做到这一点,或者是状态参数只能用作为回调委托指定某种初始状态的方式(正如我在这里所做的那样,有效地说,从42开始计数)?
亲切的愿望~Patrick
我的尝试:
给出的代码示例。我只是无法弄清楚如何编写任何比我现在做的更多的东西。
Every 5 seconds, it prints out "event...42".
When I read the MSDN documentation on Timer
(Timer Constructor (TimerCallback, Object, Int64, Int64) (System.Threading)), it says that the state parameter is: "An object containing information to be used by the callback method." This implies I can somehow pass information into the callback function each time it is called. So, in my example above, I could find a way to get the callback to print out 42...43...44... etc.
Is there any way to do this, or is the state parameter usable only as a way to specify some kind of initial state for the callback delegate (as I have done here, by effectively saying, "Start counting from 42")?
Kind wishes ~ Patrick
What I have tried:
The code example given. I just can't work out how to write anything that does "more" than what I am doing already.
推荐答案
event ... {(int)state});
}
private static int _count = 42 ;
}
}
"event...{(int)state}" ); } private static int _count = 42; } }
每5秒打印一次事件...... 42。 />
当我在计时器
上阅读MSDN文档时(Timer构造函数(TimerCallback,Object,Int64,Int64)(System.Threading)),它表示状态参数是:包含要由回调方法使用的信息的对象。这意味着每次调用时我都可以以某种方式将信息传递给回调函数。所以,在我上面的例子中,我可以找到一种方法让回调打印出42 ... 43 ... 44 ......等等。
是有没有办法做到这一点,或者是状态参数只能用作为回调委托指定某种初始状态的方式(正如我在这里所做的那样,有效地说,从42开始计数)?
亲切的愿望~Patrick
我的尝试:
给出的代码示例。我只是无法弄清楚如何编写任何比我现在做的更多的东西。
Every 5 seconds, it prints out "event...42".
When I read the MSDN documentation on Timer
(Timer Constructor (TimerCallback, Object, Int64, Int64) (System.Threading)), it says that the state parameter is: "An object containing information to be used by the callback method." This implies I can somehow pass information into the callback function each time it is called. So, in my example above, I could find a way to get the callback to print out 42...43...44... etc.
Is there any way to do this, or is the state parameter usable only as a way to specify some kind of initial state for the callback delegate (as I have done here, by effectively saying, "Start counting from 42")?
Kind wishes ~ Patrick
What I have tried:
The code example given. I just can't work out how to write anything that does "more" than what I am doing already.
我不确定它是唯一的还是最好的解决方案,但以下是代码实现了我的目标。基本上,我所做的就是将哑整数_count变量更改为一个类,这意味着它通过引用传递,它可以保持自己的内部状态,如下所示:
I am not sure if it is the only or best solution, but the following code achieves what I was looking to do. Basically, all I have done is changed the "dumb" integer _count variable to a class, which means it is passed by reference and it can maintain its own internal state, like this:
using System;
using System.Threading;
namespace ConsoleApplication1
{
public class Repeater
{
public Repeater( Action<object> callback, object state )
{
// Time takes a TimerCallback delegate, but this constructor takes an Action<object>. I have
// read the easiest way to 'cast' a delegate is using lambdas. Like this:
TimerCallback tcb = ( s ) => callback( s );
// So now I can construct my Timer.
_timer = new Timer( tcb, state, 0, 5000 );
}
private Timer _timer = null;
}
public class Counter
{
public int Count { get; set; }
}
public class Program
{
static void Main( string[] args )
{
Counter counter = new Counter();
Action<object> callback = MyFunction;
Repeater repeater = new Repeater( callback, counter );
Console.ReadKey();
}
private static void MyFunction( object state )
{
Counter counter = state as Counter;
Console.WriteLine(
event ... {counter .Count});
counter.Count = counter.Count + 1 ;
}
}
}
"event...{counter.Count}" ); counter.Count = counter.Count + 1; } } }
这似乎有效。我仍然会感激任何评论。
This seems to work. I would still appreciate any comments though.
这篇关于如何使用传递给system.threading.timer的状态对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!