SplatTool-public/FreezeThreads.cs

86 lines
2.4 KiB
C#
Raw Normal View History

2026-04-23 17:08:47 +02:00
using ModMenu;
using Func;
using System;
using System.Threading;
namespace FreezeThread {
public class WorkThread {
private Thread MainThread;
private bool running = false;
public enum ThreadStatus { Running, Paused, Stopped }
private ThreadStatus status = ThreadStatus.Stopped;
private readonly object statusLock = new object();
public ThreadStatus Status {
get {
lock (statusLock) {
return status;
}
}
private set {
lock (statusLock) {
status = value;
}
}
}
private readonly ManualResetEventSlim pauseEvent = new ManualResetEventSlim(true);
private readonly Action ThreadAction;
public WorkThread(Action ThreadAction) {
this.ThreadAction = ThreadAction
?? throw new ArgumentNullException(nameof(ThreadAction));
}
private void ThreadLoop() {
while (running) {
try {
pauseEvent.Wait();
if (pauseEvent.IsSet)
Status = ThreadStatus.Running;
ThreadAction();
Thread.Sleep(1); // Prevent CPU Exhaustion by adding small delay
} catch (ArgumentOutOfRangeException ex) {
running = false;
Status = ThreadStatus.Stopped;
Console.WriteLine($"Thread Killed! Caught: {ex}");
}
}
Status = ThreadStatus.Stopped;
}
public void Start() {
if (running)
return;
MainThread = new Thread(ThreadLoop);
MainThread.IsBackground = true;
running = true;
MainThread.Start();
}
public void Pause() {
if (Status == ThreadStatus.Running) {
pauseEvent.Reset();
Status = ThreadStatus.Paused;
}
}
public void Resume() {
if (Status == ThreadStatus.Paused) {
pauseEvent.Set();
Status = ThreadStatus.Running;
}
}
public void Stop() {
running = false;
pauseEvent.Set();
MainThread?.Join();
Status = ThreadStatus.Stopped;
}
}
}