等待线程.计时器回调函数结束

本文关键字:函数 结束 回调 计时器 线程 等待 | 更新日期: 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"));
      //...
 }

也许可以在没有新实例的情况下初始化它,但我不太确定…附注:我怀疑这不是你使用的代码,因为它甚至不能编译。注意更新它……