.Net计时器工作线程

时间:2017-05-30 09:13:44

标签: .net multithreading timer c++-cli

我目前正在尝试了解.net中的计时器如何处理多线程应用程序。使用Visual Studio 2010,.NET / C ++ / CLI 任务是有一个计时器,将在后台读取一些数据,以便我可以通过另一个计时器显示该数据。虽然很简单......

我做了一个简单的程序来观察不同的计时器是如何工作的:
1. System :: Windows :: Forms :: Timer ;
2. 系统::计时器::计时器;
3. 系统::线程::计时器;
4.和另一个 System :: Timers :: Timer ,我不是从主线程运行,而是使用System :: Threading :: Thread
所有这些都是在代码中手动制作的,还有另一个在Designer中制作的计时器,类型为System :: Windows :: Forms :: Timer
每个计时器在每个tick中为其自己的 ConcurrentQueue 类型的容器写一个字符串,并递增其计数器,即int类型的全局变量。主线程计时器将这些字符串获取到接口列表Control。

programm snapshot
所有四个定时器初始化为每500ms滴答一次 列表中的第一个数字是刻度计数器。 <> 中的文字是主题名称。
Id:是该主题的ID。
T:是在每个事件中使用 QueryPerformanceCounter()函数计算的滴答之间的实时时间。

现在我们看到计时器开始同时工作前5个刻度。我们也看到只有第一个计时器每个滴答使用相同的线程 然后我按下睡眠按钮,在主线程上实现睡眠(5000)功能,模仿它真的很忙。
正如预期的那样,第一个只是在睡眠后停止并继续 但是其他人对我来说很奇怪。我希望它们能在后台运行。但我所看到的是,计数器没有正确递增,并且刻度的时间也不正确。

我想知道的是那些定时器(Timers :: Timer和Threading :: Timer)真的以某种方式被主线程休眠函数阻止,或者它只是一个 UI bug /代码错误 或他们 工作正常

这里定时器滴答会发生什么。与每个计时器类似:

System::Void Form1::SysThrd_Tick(System::Object^  sender)
{
    static LARGE_INTEGER ticks_old, ticks_new;  //for precise counter
    double real_time=0;

    if (Thread::CurrentThread->Name == nullptr) Thread::CurrentThread->Name = "ThTm";
    Thread_Timer_Id = GetThreadId(GetCurrentThread());

    QueryPerformanceCounter(&ticks_new);  //getting precise ticks

    real_time = safe_cast<double>(ticks_new.QuadPart - ticks_old.QuadPart);
    real_time = real_time/freq.QuadPart;  //counting real time passed for tick

    ThTm_queue->Enqueue(SysThrd_tick.ToString()+" <"+Thread::CurrentThread->Name+"> Id: "+Thread_Timer_Id+"; T: "+real_time.ToString("0.000"));  //adding item to container

    SysThrd_tick++;
    ticks_old = ticks_new;
}

通过设计器计时器显示容器中的数据:

System::Void Form1::InnerTimer_Tick(System::Object^ sender, System::EventArgs^ e)
{
    String ^str;
    static int Inner_tick=0;

    InnerTimer_tB->Text = Thread::CurrentThread->Name+"::"+Inner_tick.ToString();  //text to Form1 TextBox control
    Inner_tick++;

    while (!ThTm_queue->IsEmpty) 
    {
        ThTm_queue->TryDequeue(str);  //getting item from container
        Threading_Timer_lB->Items->Add(str); //adding item to Form1 ListBox control
    }
//<similar code for other containers>
}

在Form1.h中定义的所有容器,并在main.cpp中初始化,如下所示:

void Form1::init_queues()
{
    ThTm_queue = gcnew ConcurrentQueue<String^>;
    //same code for other containers
}

Tick计数器是全局整数,在resource.h中定义

定时器在Form1.h中定义并在main.cpp中初始化,例如Threading :: Timer:

System::Void Form1::Init_Timers()
{
    //other timers initialization
    Form1::SysThrd_Timer = gcnew System::Threading::Timer((gcnew TimerCallback(this, &Form1::SysThrd_Tick)), nullptr, Threading::Timeout::Infinite, Threading::Timeout::Infinite);
}

0 个答案:

没有答案