Планирование потока C # с крайним сроком - PullRequest
0 голосов
/ 21 мая 2019

В настоящее время я пытаюсь реализовать программное обеспечение для многопоточности в реальном времени на C #. Мне нужно 3 темы. Каждое выполнение потока должно быть закончено до крайнего срока (500 мкс / 100 мкс / 50 мкс). Потоки должны работать параллельно в течение всего времени выполнения (пока пользователь не закроет программу).

Существует ли механизм, который может гарантировать, что выполнение потока не пройдет срок?

Вот мой код:

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 голосов
/ 21 мая 2019

Вот метод, который повторно вызывает действие в фоновом потоке, прерывает и перезапускает поток каждый раз, когда истекает крайний срок. Он также принимает 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);

Следует отметить, что прерывание потоков не является хорошей практикой в целом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...