我启动了一个带回调函数的计时器。但是在这个回调函数中,我更改/初始化了一个静态对象,该对象在启动计时器后使用。
public class TimerExecute
{
// Assume that the "Dog" class exist with attribute Name initialized in the constructor
public static List<Dog> listDog = new List<Dog>();
public void callbackFunct(String param) {
// code...
listDog.Add(new Dog("Bob"));
// code...
}
public void Main() {
// add dogs Bob each 10sec
Timer addbobs = new Timer((e) => callbackFunct("arg"), null, 0, 10000);
// return argumentoutofrange exception
Console.WriteLine(listDog[0].name);
}
}
当我使用静态var时,我有一个异常“参数超出范围异常”。我认为问题在于回调函数没有完成执行并且对象尚未初始化。
我试过这个解决方案,但这不起作用:
// add dogs Bob each 10sec
Timer addbobs = new Timer((e) => callbackFunct("arg"), null, 0, 10000);
WaitHandle h = new AutoResetEvent(false);
addbobs.Dispose(h);
Console.WriteLine(listDog[0].name);
但有了它,它的确有效:
Timer addbobs = new Timer((e) => callbackFunct("arg"), null, 0, 10000);
Thread.Sleep(2000);
Console.WriteLine(listDog[0].name);
我希望我的回调函数在下一个语句之前完成执行。 你有解决我的问题的方法吗?
上次编辑:是的我希望能够将参数传递给callbackFunct
答案 0 :(得分:1)
这是我想出的。诀窍是传入AutoResetEvent
,你必须自己在那个事件上调用Set()
,这就是该方法已经完成的信号&#34; (实际上它只是表示方法被调用,无论方法是否完成)。因为看起来除了WaitHandle
之外你还需要发送回调用的其他参数,所以我创建了一个类来封装它们。
public void callbackFunct(object state)
{
var myParams = (CustomParametersWithWaitHandle)state;
string name = myParams.Parameter1;
AutoResetEvent wh = myParams.WaitHandle;
// code...
listDog.Add(new Dog(name));
// code...
wh.Set(); // signal that this callback is done
}
public void Main()
{
// add dogs Bob each 10sec
AutoResetEvent wh = new AutoResetEvent(false);
var myCustomParams = new CustomParametersWithWaitHandle(wh, "bob", 314);
Timer addbobs = new Timer(new TimerCallback(callbackFunct), myCustomParams, 0, 10000);
wh.WaitOne(); // blocks here until `Set()` is called on the AutoResetEvent
Console.WriteLine(listDog[0].name);
}
}
public class CustomParametersWithWaitHandle
{
public AutoResetEvent WaitHandle { get; set; }
public string Parameter1 { get; set; }
public int Parameter2 { get; set; }
public CustomParametersWithWaitHandle(AutoResetEvent h, string parameter1, int parameter2)
{
WaitHandle = h;
Parameter1 = parameter1;
Parameter2 = parameter2;
}
答案 1 :(得分:0)
我非常确定您应该使用TimerCallback
初始化new TimerCallback(callbackFunct)
而不是仅使用函数的名称。这应该是你的名单没有被Bobs填充的原因(我似乎无法理解它甚至可以编译但是...)。像:
Timer addbobs = new Timer(new TimerCallback(callbackFunct), null, 0, 10000);
您的功能应如下所示:
public void callbackFunct(object state){
//...
listDog.Add(new Dog("Bob"));
//...
}
有可能在没有新实例的情况下初始化它,但我不太确定...... P.S。:我怀疑这不是您正在使用的代码,因为它甚至无法编译。注意更新它......