等待线程.计时器回调函数结束
本文关键字:函数 结束 回调 计时器 线程 等待 | 更新日期: 2023-09-27 17:52:17
我启动一个带有回调函数的计时器。但是在这个回调函数中,我更改/初始化了一个静态对象,该对象在timer启动后使用。
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);
}
}
当我使用静态变量时,我有一个异常"参数超出范围异常"。我认为问题是回调函数没有完成她的执行,对象还没有初始化。
我尝试了这个解决方案,但这不起作用:
// 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
这是我想到的。诀窍是传递AutoResetEvent
,并且您必须自己在该事件上调用Set()
,这是方法"完成"的信号(实际上它只是表明无论方法是否完成都调用了该方法)。因为除了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;
}
我很确定您应该用new TimerCallback(callbackFunct)
初始化您的TimerCallback
,而不仅仅是函数的名称。这应该是你的列表没有被bob填满的原因(我似乎不明白它是如何编译的,但是……)。如:
Timer addbobs = new Timer(new TimerCallback(callbackFunct), null, 0, 10000);
你的函数应该是这样的:
public void callbackFunct(object state){
//...
listDog.Add(new Dog("Bob"));
//...
}
也许可以在没有新实例的情况下初始化它,但我不太确定…附注:我怀疑这不是你使用的代码,因为它甚至不能编译。注意更新它……