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