每n秒唤醒一次线程

发布于 2024-11-08 12:46:55 字数 800 浏览 4 评论 0原文

我正在使用 C# 编写 WPF 应用程序,并且需要一些线程方面的帮助。我有三个类,每个类都需要在自己的线程中每 n 秒运行一个任务。这就是我使用 Qt4 所做的:

class myThread : public QThread
{
    void run (void)
    {
        while (true)
        {
            mMutex.lock();
            mWaitCondition.wait (&mMutex);

            // Some task

            mMutex.unlock();
        }
    }

    void wait (int timeout)
    {
        // For shutdown purposes
        if (mMutex.tryLock (timeout))
            mMutex.unlock();
    }

    void wake (void)
    {
        mWaitCondition.wakeAll();
    }
}

// Some other class has a timer which ticks
// every n seconds calling the wake function
// of the myThread class.

我从中得到的是受控的更新间隔。因此,如果我每秒更新 60 次,如果代码很慢并且每秒只能运行 30 次,这样做没有问题,但它永远不会运行超过每秒 60 次。它也不会同时运行同一代码多次。在 C# 中实现此功能的最简单方法是什么?

I am writing a WPF application using C# and I need some help with threading. I have three classes, each need to be running a task every n seconds in their own thread. This is how I did it with Qt4:

class myThread : public QThread
{
    void run (void)
    {
        while (true)
        {
            mMutex.lock();
            mWaitCondition.wait (&mMutex);

            // Some task

            mMutex.unlock();
        }
    }

    void wait (int timeout)
    {
        // For shutdown purposes
        if (mMutex.tryLock (timeout))
            mMutex.unlock();
    }

    void wake (void)
    {
        mWaitCondition.wakeAll();
    }
}

// Some other class has a timer which ticks
// every n seconds calling the wake function
// of the myThread class.

What I get from this is a controlled update interval. So if I am updating 60 times a second, if the code is slow and can only run 30 times a second, it has no problem doing that, but it will never run more than 60 times a second. It will also not run the same code more than one time at the same time. Whats the easiest way of implementing this in C#?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

彩扇题诗 2024-11-15 12:46:55

您应该使用Timer来代替。

阅读本文了解详细信息,或这个 以获得更简洁的解释。

You should use a Timer instead.

Read this article for details, or this one for a more compact explanation.

花辞树 2024-11-15 12:46:55

.NET 响应式扩展 允许复杂的、基于时间的异步事件组合 - < a href="http://rxwiki.wikidot.com/101samples#toc24" rel="nofollow">这可能是时间相关行为的一个很好的起点。

.NET Reactive Extensions allow for complex, time-based, asynchronous event composition - this is probably a good starting point for time related behaviors.

羞稚 2024-11-15 12:46:55

使用这些类来执行此操作

using System;
using System.Timers;
using System.Threading;

public class ClassTask
{
    System.Timers.Timer timer = null;

    public bool IsRunning { get; set; }

    public DateTime LastRunTime { get; set; }

    public bool IsLastRunSuccessful { get; set; }

    public double Interval { get; set; }

    public bool Stopped { get; set; }

    public ClassTask(double interval)
    {
        this.Interval = interval;
        this.Stopped = false;
        timer = new System.Timers.Timer(this.Interval);
        timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
        timer.Enabled = true;
    }
    public void Start()
    {
        this.Stopped = false;
        this.StartTask();
    }

    public void Stop()
    {
        this.Stopped = true;
    }

    private void StartTask()
    {
        if (!this.Stopped)
        {
            //Thread thread = new Thread(new ThreadStart(Execute));
            //thread.Start();
            Execute();
        }
    }

    private void Execute()
    {
        try
        {
            this.IsRunning = true;
            this.LastRunTime = DateTime.Now;

            // Write code here

            this.IsLastRunSuccessful = true;
        }
        catch
        {
            this.IsLastRunSuccessful = false;
        }
        finally
        {
            this.IsRunning = false;
        }
    }

    void timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        if (!this.IsRunning)
            StartTask();
    }
}

using System;
using System.Data;
using System.Configuration;

public class ClassTaskScheduler
{
    ClassTask task = null;

    public ClassTaskScheduler()
    {
        this.task = new ClassTask(60000);
    }

    public void StartTask()
    {
        this.task.Start();
    }

    public void StopTask()
    {
        this.task.Stop();
    }
}

您可以在 global.asax 中或您想要调用它的地方

void Application_Start(object sender, EventArgs e) 
    {
        // Code that runs on application startup
        ClassTaskScheduler _scheduler = new ClassTaskScheduler();
        _scheduler.StartTask();
    }

    void Application_End(object sender, EventArgs e) 
    {
        //  Code that runs on application shutdown
        ClassTaskScheduler _scheduler = new ClassTaskScheduler();
        _scheduler.StopTask();
    }

您可以使用 Execute() 函数在给定的时间间隔内运行任务......

You can use there classes for do this

using System;
using System.Timers;
using System.Threading;

public class ClassTask
{
    System.Timers.Timer timer = null;

    public bool IsRunning { get; set; }

    public DateTime LastRunTime { get; set; }

    public bool IsLastRunSuccessful { get; set; }

    public double Interval { get; set; }

    public bool Stopped { get; set; }

    public ClassTask(double interval)
    {
        this.Interval = interval;
        this.Stopped = false;
        timer = new System.Timers.Timer(this.Interval);
        timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
        timer.Enabled = true;
    }
    public void Start()
    {
        this.Stopped = false;
        this.StartTask();
    }

    public void Stop()
    {
        this.Stopped = true;
    }

    private void StartTask()
    {
        if (!this.Stopped)
        {
            //Thread thread = new Thread(new ThreadStart(Execute));
            //thread.Start();
            Execute();
        }
    }

    private void Execute()
    {
        try
        {
            this.IsRunning = true;
            this.LastRunTime = DateTime.Now;

            // Write code here

            this.IsLastRunSuccessful = true;
        }
        catch
        {
            this.IsLastRunSuccessful = false;
        }
        finally
        {
            this.IsRunning = false;
        }
    }

    void timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        if (!this.IsRunning)
            StartTask();
    }
}

using System;
using System.Data;
using System.Configuration;

public class ClassTaskScheduler
{
    ClassTask task = null;

    public ClassTaskScheduler()
    {
        this.task = new ClassTask(60000);
    }

    public void StartTask()
    {
        this.task.Start();
    }

    public void StopTask()
    {
        this.task.Stop();
    }
}

In global.asax or where you want to call this

void Application_Start(object sender, EventArgs e) 
    {
        // Code that runs on application startup
        ClassTaskScheduler _scheduler = new ClassTaskScheduler();
        _scheduler.StartTask();
    }

    void Application_End(object sender, EventArgs e) 
    {
        //  Code that runs on application shutdown
        ClassTaskScheduler _scheduler = new ClassTaskScheduler();
        _scheduler.StopTask();
    }

You can use Execute() function for run task in given time interval....

半边脸i 2024-11-15 12:46:55

.NET 中的等效方法是使用 ManualResetEvent。使用带有超时的 WaitOne 方法来引发等待。它还可以兼作关闭机制。这种方法的好处是很简单,所有东西都运行一个线程,并且相同的代码不能并行执行(因为它都在一个线程上)。

class myThread
{
  private ManualResetEvent m_WaitHandle = new ManualResetEvent(false);

  public myThread
  {
    new Thread(Run).Start();
  }

  public void Shutdown()
  {
    m_WaitHandle.Set(); // Signal the wait handle.
  }

  private void Run()
  {
    while (!m_WaitHandle.WaitOne(INTERVAL)) // The waiting happens here.
    {
      // Some task
    }
    // If execution gets here then the wait handle was signaled from the Shutdown method.
  }
}

The equivalent in .NET would be to use a ManualResetEvent. Use the WaitOne method with a timeout to cause the waiting. It can also double as the shutdown mechanism. The nice thing about this approach is that is simple, everything runs one thread, and the same code cannot be executing in parallel (because it is all on one thread).

class myThread
{
  private ManualResetEvent m_WaitHandle = new ManualResetEvent(false);

  public myThread
  {
    new Thread(Run).Start();
  }

  public void Shutdown()
  {
    m_WaitHandle.Set(); // Signal the wait handle.
  }

  private void Run()
  {
    while (!m_WaitHandle.WaitOne(INTERVAL)) // The waiting happens here.
    {
      // Some task
    }
    // If execution gets here then the wait handle was signaled from the Shutdown method.
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文