C# 从后台线程调用计时器

C# 从后台线程调用计时器,c#,multithreading,timer,C#,Multithreading,Timer,我想做的事。我想知道某个方法将定期调用。所以,我想在后台线程方法的主体被传递之后,计时器将从后台线程启动\u timer.Start()已调用,但TickHandler未调用 代码: 通过monkey方法,我发现如果像这样添加委托 internal delegate void TimerDelegate(); 并替换字符串 TimerStart(); 与 一切正常。有人能告诉我这是什么把戏吗 你把事情搞混了 如果您想要一个在后台线程上触发的计时器,则不必创建线程来启动它(无论哪个线程调用s

我想做的事。我想知道某个方法将定期调用。所以,我想在后台线程方法的主体被传递之后,计时器将从后台线程启动<代码>\u timer.Start()已调用,但TickHandler未调用

代码:

通过monkey方法,我发现如果像这样添加委托

internal delegate void TimerDelegate();
并替换字符串

TimerStart(); 


一切正常。有人能告诉我这是什么把戏吗

你把事情搞混了

如果您想要一个在后台线程上触发的计时器,则不必创建线程来启动它(无论哪个线程调用
start
方法)。只需使用
System.Timers.Timer
,每个
经过的事件都将发生在线程池线程上

如果您想要在UI线程上触发计时器,因为它看起来像是在使用WPF,您应该使用
System.Windows.Threading.dispatchermer
,而不是一直使用的Windows窗体计时器。您应该在特定UI线程上创建计时器(即调用
new
),并且每个
Tick
事件都将在该线程上发生。同样,从哪个线程调用
Start
并不重要

下面解释一下代码中发生的情况:您正在非UI线程上启动Windows窗体计时器。这种计时器需要在该线程上运行消息泵,以便它可以接收消息。因为它是非UI线程,所以没有消息泵。当您使用
Dispatcher.Invoke
方法时,您将计时器的创建封送回应用程序的主UI线程,从而使其正常工作。但这一切都是多余的。如果要保持代码不变,只需将计时器替换为
分派器
,然后就可以删除
调用
调用

或者,如果您使用的是.NET 4.5,则可以使用wait/async使这一切变得更容易(请确保从UI线程调用
SomeMethod
):


你把事情搞混了

如果您想要一个在后台线程上触发的计时器,则不必创建线程来启动它(无论哪个线程调用
start
方法)。只需使用
System.Timers.Timer
,每个
经过的事件都将发生在线程池线程上

如果您想要在UI线程上触发计时器,因为它看起来像是在使用WPF,您应该使用
System.Windows.Threading.dispatchermer
,而不是一直使用的Windows窗体计时器。您应该在特定UI线程上创建计时器(即调用
new
),并且每个
Tick
事件都将在该线程上发生。同样,从哪个线程调用
Start
并不重要

下面解释一下代码中发生的情况:您正在非UI线程上启动Windows窗体计时器。这种计时器需要在该线程上运行消息泵,以便它可以接收消息。因为它是非UI线程,所以没有消息泵。当您使用
Dispatcher.Invoke
方法时,您将计时器的创建封送回应用程序的主UI线程,从而使其正常工作。但这一切都是多余的。如果要保持代码不变,只需将计时器替换为
分派器
,然后就可以删除
调用
调用

或者,如果您使用的是.NET 4.5,则可以使用wait/async使这一切变得更容易(请确保从UI线程调用
SomeMethod
):

我可以为您解释一下:

注意Windows窗体计时器组件是单线程的,并且是 精度限制为55毫秒。如果您需要 要获得更高精度的多线程计时器,请使用 Timers命名空间

我可以为您解释一下:

注意Windows窗体计时器组件是单线程的,并且是 精度限制为55毫秒。如果您需要 要获得更高精度的多线程计时器,请使用 Timers命名空间


我想要一个在UI线程上触发的计时器,但我强制从后台线程启动它。我不创建后台线程来启动计时器:),我使用后台线程来执行一些操作,在这些操作之后,我希望重新启动计时器。所以,实际上,我需要UI线程的启动计时器,但我不知道后台线程何时完成工作。因此,我尝试从后台线程启动计时器。无论如何,我理解你,几乎。。。我想我需要阅读更多关于线程的内容。明白了:)试着阅读任务和异步。我想要一个在UI线程上启动的计时器,但是我强制从后台线程启动它。我不创建后台线程来启动计时器:),我使用后台线程来执行一些操作,在这些操作之后,我希望重新启动计时器。所以,实际上,我需要UI线程的启动计时器,但我不知道后台线程何时完成工作。因此,我尝试从后台线程启动计时器。无论如何,我理解你,几乎。。。我想我需要阅读更多关于线程的内容。明白了:)试着阅读任务和异步。它们使线程的使用更加简单。
TimerStart(); 
Application.Current.Dispatcher.Invoke(new TimerDelegate(TimerStart), null);
async Task SomeMethod(CancellationToken ct)
{
    while (!ct.IsCancellationRequested)
    {
        await Task.Run(() => DoAsyncStuff(), ct);

        DoUIStuff();

        await Task.Delay(TimeSpan.FromMinutes(1), ct);
    }
}