具有截止日期的C#线程调度

时间:2019-05-21 13:18:53

标签: c# multithreading scheduled-tasks multitasking

我目前正在尝试在C#中实现实时多线程软件。我需要3个线程。每个线程执行必须在截止期限(500µs / 100µs / 50µs)之前完成。在整个运行期间,线程必须并行运行(直到用户关闭程序)。

是否存在可以确保线程执行不会超过期限的机制?

这是我的代码:

static void Main(string[] args)
{
    Thread thread1 = new Thread(FirstThread);
    Thread thread2 = new Thread(SecondThread);
    Thread thread3 = new Thread(ThirdThread);

    thread1.start();
    thread2.start();
    thread3.start();
}

static void FirstThread()
{
    while(true)
    {
        SleepMicroSec(500);
    }
}

static void SecondThread()
{
    while(true)
    {
        SleepMicroSec(100);
    }
}

static void ThirdThread()
{
    while(true)
    {
        SleepMicroSec(50);
    }
}

private static void SleepMicroSec(long microSec)
{
    var sw = Stopwatch.StartNew();

    while (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L)) < microSec)
    {

    }
}

如果达到任务期限,我希望调度程序能够执行上下文切换。

预先感谢您的回答!

1 个答案:

答案 0 :(得分:-1)

这里是一种在后台线程中重复调用动作的方法,每次超过期限时,都会中止并重新启动线程。它还接受CancellationToken以允许过早取消该过程(在程序结束之前)。

private static void RepeatInBackgroundThread(Action action, int timeout,
    CancellationToken cancellationToken)
{
    var timer = new System.Timers.Timer(timeout);
    timer.AutoReset = false; // to raise the Elapsed event only once
    var thread = new Thread(() =>
    {
        while (true)
        {
            if (cancellationToken.IsCancellationRequested) return;
            timer.Start();
            action();
            timer.Stop();
        }
    });
    timer.Elapsed += (sender, e) =>
    {
        thread.Abort();
        thread.Join(); // Wait for the thread to die
        if (cancellationToken.IsCancellationRequested) return;
        RepeatInBackgroundThread(action, timeout, cancellationToken);
    };
    thread.IsBackground = true;
    thread.Start();
}

用法示例:

var random = new ThreadLocal<Random>(() => new Random());
var cts = new CancellationTokenSource();
RepeatInBackgroundThread(() => Thread.Sleep(random.Value.Next(0, 1000)), 500, cts.Token);
RepeatInBackgroundThread(() => Thread.Sleep(random.Value.Next(0, 200)), 100, cts.Token);
RepeatInBackgroundThread(() => Thread.Sleep(random.Value.Next(0, 100)), 50, cts.Token);
//cts.CancelAfter(10000);

应该注意,一般aborting threads is not a good practice