Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 后台计时器仅在一个线程C中工作#_C#_Wpf_Multithreading_C# 4.0_Timer - Fatal编程技术网

C# 后台计时器仅在一个线程C中工作#

C# 后台计时器仅在一个线程C中工作#,c#,wpf,multithreading,c#-4.0,timer,C#,Wpf,Multithreading,C# 4.0,Timer,我有一个棘手的问题,我正在使用.NET 4.0中的C#和WPF,我需要的是一个计时器,它只会创建一个线程,但它需要在后台工作,所以不需要在主线程中工作,问题在于使用System.Windows.Forms.Timer或DispatchTimer将自动强制其在主线程上工作并受UI的影响,而在另一端,使用System.Timer.Timer或System.Threading.Timer将为超出时间间隔的每个周期创建一个新线程,这将发生,因为“已用计时器”事件中的代码有点大,尽管部分代码会进一步发送到

我有一个棘手的问题,我正在使用.NET 4.0中的C#和WPF,我需要的是一个计时器,它只会创建一个线程,但它需要在后台工作,所以不需要在主线程中工作,问题在于使用System.Windows.Forms.Timer或DispatchTimer将自动强制其在主线程上工作并受UI的影响,而在另一端,使用System.Timer.Timer或System.Threading.Timer将为超出时间间隔的每个周期创建一个新线程,这将发生,因为“已用计时器”事件中的代码有点大,尽管部分代码会进一步发送到后台工作程序


因此,我在想,如果可以强制(比如System.Timers.Timer)在后台工作,并且不会产生超过一个线程,那么我也愿意接受其他建议,只需使用周期为0的System.Threading.Timer,以便回调只运行一次。当一切都完成后,给计时器充电,以便它稍后再次启动。您将保证只有一个线程以这种方式运行。

只需使用周期为0的System.Threading.Timer,以便回调只运行一次。当一切都完成后,给计时器充电,以便它稍后再次启动。您将保证只有一个线程以这种方式运行。

使用System.Timers.Timer,它将在线程池线程上触发其已用事件处理程序。进入事件处理程序后,立即停止计时器。在事件处理程序结束时,启动计时器,计时器将从其间隔开始倒计时

下面是一个简单的示例,其中100ms计时器在其已用事件处理程序中花费2秒:

static void Main(string[] args)
{
    System.Timers.Timer myTimer = new System.Timers.Timer(100);
    myTimer.Elapsed += new System.Timers.ElapsedEventHandler(myTimer_Elapsed);
    myTimer.Start();
    Console.ReadLine();
}

static void myTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    ((System.Timers.Timer)sender).Stop();
    Console.WriteLine(DateTime.Now.ToString("HH.mm.ss"));
    System.Threading.Thread.Sleep(2000);
    ((System.Timers.Timer)sender).Start();
}

使用System.Timers.Timer,它在线程池线程上触发其已用事件处理程序。进入事件处理程序后,立即停止计时器。在事件处理程序结束时,启动计时器,计时器将从其间隔开始倒计时

下面是一个简单的示例,其中100ms计时器在其已用事件处理程序中花费2秒:

static void Main(string[] args)
{
    System.Timers.Timer myTimer = new System.Timers.Timer(100);
    myTimer.Elapsed += new System.Timers.ElapsedEventHandler(myTimer_Elapsed);
    myTimer.Start();
    Console.ReadLine();
}

static void myTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    ((System.Timers.Timer)sender).Stop();
    Console.WriteLine(DateTime.Now.ToString("HH.mm.ss"));
    System.Threading.Thread.Sleep(2000);
    ((System.Timers.Timer)sender).Start();
}

Dispatchermer有一个构造函数重载,可以让您完全按照自己的意愿进行操作。 在线程的上下文中使用它:

using System.Threading;
using WpfThreading = System.Windows.Threading;

...

Thread t = new Thread(() => 
{
    var interval = TimeSpan.FromSeconds(3.0);
    var priority = WpfThreading.DispatcherPriority.Background;
    EventHandler callback = (a, e) => { };
    var dispatcher = WpfThreading.Dispatcher.CurrentDispatcher; // dispatcher for this thread
    WpfThreading.DispatcherTimer dt = new WpfThreading.DispatcherTimer(interval, priority, callback, dispatcher);

    bool sameDispatchers = WpfThreading.Dispatcher.CurrentDispatcher == this.Dispatcher; // false
});
t.Start();

Dispatchermer有一个构造函数重载,可以让您完全按照自己的意愿进行操作。 在线程的上下文中使用它:

using System.Threading;
using WpfThreading = System.Windows.Threading;

...

Thread t = new Thread(() => 
{
    var interval = TimeSpan.FromSeconds(3.0);
    var priority = WpfThreading.DispatcherPriority.Background;
    EventHandler callback = (a, e) => { };
    var dispatcher = WpfThreading.Dispatcher.CurrentDispatcher; // dispatcher for this thread
    WpfThreading.DispatcherTimer dt = new WpfThreading.DispatcherTimer(interval, priority, callback, dispatcher);

    bool sameDispatchers = WpfThreading.Dispatcher.CurrentDispatcher == this.Dispatcher; // false
});
t.Start();

如果在当前周期仍在处理的情况下发生下一个勾号,您希望发生什么?您试图用后台线程实现什么?这只是需要运行的东西吗,计时器需要确保线程存在吗?@justin:我想在当前周期结束时等待processing@paul:基本上,它需要运行和算法,我不想被GUI打断,GUI有一些中等GFX类型的语音,如果在当前周期仍在运行时出现下一个滴答声,您希望发生什么处理?你想用后台线程完成什么?这只是需要运行的东西,计时器需要确保线程存在吗?@justin:我想在当前周期结束时等待processing@paul:基本上它需要运行和算法,我不想被GUI打断,它有一些中等GFX类型的语音是的,谢谢,这似乎是获取所需内容的最简单方法System.Threading.Timer也会在线程池线程中执行,这样做的好处是不必在每次发生事件时重新初始化它。是的,谢谢,这似乎是获取所需内容的最简单方法System.Threading.Timer也会在线程池线程中执行,这样做的好处是不必在每次发生事件时重新初始化它。