开发者

Waking thread every n seconds

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 (&mMute开发者_JAVA技巧x);

            // 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#?


You should use a Timer instead.

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


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


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....


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.
  }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜