我想将变量传递给延迟后运行的函数。我已经看到了关于如何做到这一点的类似问题(见下文)。我不认为这是我想要的,因为每次调用method1
时,附加的匿名函数的数量会增加吗?我需要做的是删除任何现有的附加匿名函数,然后再添加新函数。但我不认为这是可能的。有没有办法在延迟后调用方法,但每次传递一个新的变量值?
using System.Timers;
myTimer = new Timer();
myTimer.Interval = 3000;
myTimer.AutoReset = false;
public void method1(int var1){
myTimer.Elapsed += delegate { doSomething(var1); };
myTimer.Start();
}
public void doSomething(int arg1){...}
更新
基本上每当method1
运行时,我希望在3秒后发生一些事情,我需要传入一个可能每次都有变化的参数。
我不认为我可以使用字段来存储变量,因为在第一个计时器到期之前可能会多次调用method1
。即可能有几个qued up。例如。在某个时间点,'doSomething'等待发生的问题可能是......
doSomething(3)
doSomething(7)
doSomething(1)
它只是在测试平台中使用,method1
将被调用不超过50次。我想要确保的是每个doSomething(var1)
只被调用一次而不是每3秒调用一次。也就是说,每次调用doSomething
时只会调用一个method1
。
这适用于Windows控制台应用。
答案 0 :(得分:5)
使用TPL(& .Net 4.5),您可以执行以下操作:
public static class ActionExtensions
{
public static async void DelayFor(this Action act, TimeSpan delay)
{
await Task.Delay(delay);
act();
}
}
//usage
Action toDo = () => doSomething(var1);
toDo.DelayFor(TimeSpan.FromSeconds(3));
...或者这对您的应用来说可能更简单:
static async void DoSomethingLater(int n)
{
await Task.Delay(TimeSpan.FromSeconds(3));
//DoSomething(n);
}
//usage
void Method1(int n)
{
DoSomethingLater(n);
}
答案 1 :(得分:3)
使用System.Timers.Timer
无法做到这一点。
使用System.Threading.Timer
,您可以将userState
对象传递给构造函数。然后,每个tick都将该对象传递给计时器回调。例如:
string Whatever = "foo";
System.Threading.Timer timer =
new System.Threading.Timer(MyTimerCallback, whatever, 100, 100);
void MyTimerCallback (object state)
{
string theData = (string)state;
// at this point, theData is a reference to the "Whatever" string.
// do tick processing
}
如果需要,您可以扩展System.Timers.Timer
,并添加一个属性来保存您的数据。类似的东西:
class DerivedTimer : System.Timers.Timer
{
public string Foo { get; set; }
}
myTimer = new DerivedTimer();
myTimer.Interval = 3000;
public void methodRunRegularly(int var1){
myTimer.Foo = "Foobar!";
myTimer.Elapsed += doSomething;
myTimer.Start();
}
public void doSomething(object sender, EventArgs e)
{
var t = (DerivedTimer)sender;
var foo = t.Foo;
// do processing
}
在sender
参数中传递对计时器的引用。您可以强制转换它,然后引用初始化计时器时设置的Foo
属性。
答案 2 :(得分:3)
这使用了Reactive Extensions(使用nuget包“rx-main”)。
运行延迟3秒的方法:
public void method1(int value)
{
ThreadPoolScheduler.Instance.Schedule(
TimeSpan.FromSeconds(3), () => doSomething(value));
}
这差不多就足够了!