[英]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.