延迟后调用方法(带参数)

我想将一个变量传递给一个在延迟后运行的函数。 我已经看到了关于如何做到这一点的类似问题(见下文)。 我不认为这是我想要的,因为每次调用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){...} 

UPDATE

基本上每当method1运行时,我希望在3秒后发生一些事情,我需要传入一个每次都可能变化的参数。

我不认为我可以使用字段来存储变量,因为在第一个计时器到期之前可能会多次调用method1 。 即可能有几个qued up。 例如,在某个时间点,’doSomething’等待发生的问题可能是……

 doSomething(3) doSomething(7) doSomething(1) 

它仅用于测试平台,而method1将被调用不超过50次。 我想要确保的是每个doSomething(var1)只被调用一次而不是每3秒调用一次。 即每次调用method1只调用一个doSomething

这是一个Windows控制台应用程序。

使用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); } 

使用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属性。

这使用了Reactive Extensions(使用nuget包“rx-main”)。

运行延迟3秒的方法:

 public void method1(int value) { ThreadPoolScheduler.Instance.Schedule( TimeSpan.FromSeconds(3), () => doSomething(value)); } 

那差不多就是它!