繁体   English   中英

C#单独线程在计时器上调用方法(计时器超出范围)

[英]C# separate thread that calls a method on a timer (Timer out of scope)

我有一个程序的工作版本,其中程序的主要部分使用forms.timer在与GUI相同的线程上运行。

我正在尝试升级到使用2个线程的更好的版本。 我的一个线程(处理所有信息)需要被重复调用(在计时器上)。

我在我的主要课堂上使用以下内容:

Timer tmr = new Timer(new TimerCallback(bot.refresh), null, 0, 1000);

bot.refresh是我想每秒(1000ms)调用一次的方法,直到我停止它为止。

public void refresh(Object obj)
{
        Debug.WriteLine("Updated: " + DateTime.Now.ToString());
}

大约三分之一的时间计时器将停止运行,我将得到以下输出:

Updated: 23/11/2013 4:37:24 PM
Updated: 23/11/2013 4:37:25 PM
Updated: 23/11/2013 4:37:26 PM
Updated: 23/11/2013 4:37:27 PM
Updated: 23/11/2013 4:37:28 PM
Updated: 23/11/2013 4:37:29 PM
Updated: 23/11/2013 4:37:30 PM
The thread '<No Name>' (0x3f20) has exited with code 0 (0x0).
The thread '<No Name>' (0x37a0) has exited with code 0 (0x0).

为什么会发生这种情况有什么建议吗?

另外, 有没有更好的方法可以做到这一点? 我觉得这是一种奇怪的方式。

谢谢你的帮助。

编辑:

这会超出范围吗? 这样,我可以在需要时启动计时器,而不是在构造Main时启动计时器。 要引用它,它是否必须在构造函数中?

class Main
{
    Timer tmr;
    public Main()
    {

    }

    public void start()
    {
         tmr = new Timer (new TimerCallback(bot.refresh), null, 0, 1000);
    }
}

谢谢。

您的计时器超出范围,最终被垃圾回收并停止运行。 您必须保留对它的引用,这样它才不会超出范围。

class MainClass
{
    public MainClass()
    {
        tmr = new Timer(new TimerCallback(bot.refresh), null, 0, 1000);
    }

    Timer tmr;
}

至于更好的处理方法,这取决于bot.refresh在做什么。 但是,如果可能的话,我将使用Consumer-Producer模型,并具有第二个线程刚处理时就会处理的“排队工作”的集合(这可能根本对您不起作用,就像我说的那样,这取决于bot.refesh作品。)

class MainClass
{
    public MainClass()
    {
        bot = new Bot();
        botDataProducer = BotDataProducer();
        dataQueue = new BlockingCollection<BotData>();
        consumer = Task.Factory.Run(() => ProcessData, TaskCreationOptions.LongRunning);
        producer = Task.Factory.Run(() => GenerateData, TaskCreationOptions.LongRunning);

    }

    BlockingCollection<BotData> dataQueue;
    Task consumer;
    Task producer;
    Bot bot;
    BotDataProducer botDataProducer;

    private void ProcessData()
    {
        //blocks the thread when there is no data, automatically wakes up when data is added.
        foreach(var data in dataQueue.GetConsumingEnumerable())
        {
            bot.Refresh(data);
        }
    }

    private void GenerateData()
    {
        //Assume Next() returns "false" when there will be no more data to process
        // and blocks when there is no data currently but more could come.
        while(botDataProducer.Next())
        {
            dataQueue.Add(botDataProducer.Data);
        }

        //This allows the foreach loop in the other thread to exit when the queue is empty.
        dataQueue.CompleteAdding();
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM