wabbajack/Wabbajack.Common/WorkQueue.cs

101 lines
2.9 KiB
C#
Raw Normal View History

2019-07-22 22:17:46 +00:00
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reactive;
using System.Reactive.Concurrency;
using System.Reactive.Linq;
using System.Reactive.Subjects;
2019-07-22 22:17:46 +00:00
using System.Threading;
namespace Wabbajack.Common
{
public class WorkQueue
{
2019-09-14 04:35:42 +00:00
internal static BlockingCollection<Action>
Queue = new BlockingCollection<Action>(new ConcurrentStack<Action>());
2019-07-22 22:17:46 +00:00
2019-09-14 04:35:42 +00:00
[ThreadStatic] private static int CpuId;
2019-07-22 22:17:46 +00:00
2019-09-14 04:35:42 +00:00
[ThreadStatic] internal static bool WorkerThread;
2019-10-20 11:26:42 +00:00
[ThreadStatic] public static Action<int, string> CustomReportFn;
2019-09-14 04:35:42 +00:00
public static int MaxQueueSize;
public static int CurrentQueueSize;
private readonly static Subject<CPUStatus> _Status = new Subject<CPUStatus>();
public static IObservable<CPUStatus> Status => _Status;
private readonly static Subject<(int Current, int Max)> _QueueSize = new Subject<(int Current, int Max)>();
public static IObservable<(int Current, int Max)> QueueSize => _QueueSize;
public static int ThreadCount { get; } = Environment.ProcessorCount;
2019-09-14 04:35:42 +00:00
public static List<Thread> Threads { get; private set; }
2019-08-10 15:21:50 +00:00
static WorkQueue()
2019-07-22 22:17:46 +00:00
{
StartThreads();
}
private static void StartThreads()
{
Threads = Enumerable.Range(0, ThreadCount)
2019-09-14 04:35:42 +00:00
.Select(idx =>
{
var thread = new Thread(() => ThreadBody(idx));
thread.Priority = ThreadPriority.BelowNormal;
thread.IsBackground = true;
thread.Name = string.Format("Wabbajack_Worker_{0}", idx);
thread.Start();
return thread;
}).ToList();
2019-07-22 22:17:46 +00:00
}
private static void ThreadBody(int idx)
{
CpuId = idx;
2019-08-10 15:21:50 +00:00
WorkerThread = true;
2019-07-22 22:17:46 +00:00
2019-09-14 04:35:42 +00:00
while (true)
2019-07-22 22:17:46 +00:00
{
Report("Waiting", 0);
var f = Queue.Take();
f();
}
}
2019-09-14 04:35:42 +00:00
2019-07-22 22:17:46 +00:00
public static void Report(string msg, int progress)
{
2019-10-20 11:26:42 +00:00
if (CustomReportFn != null)
{
2019-10-20 11:26:42 +00:00
CustomReportFn(progress, msg);
}
2019-10-20 11:26:42 +00:00
else
{
_Status.OnNext(
new CPUStatus
{
Progress = progress,
Msg = msg,
ID = CpuId
});
}
2019-07-22 22:17:46 +00:00
}
public static void QueueTask(Action a)
{
Queue.Add(a);
}
2019-08-02 23:04:04 +00:00
internal static void ReportNow()
{
_QueueSize.OnNext((MaxQueueSize, CurrentQueueSize));
2019-08-02 23:04:04 +00:00
}
2019-07-22 22:17:46 +00:00
}
public class CPUStatus
{
public int Progress { get; internal set; }
public string Msg { get; internal set; }
public int ID { get; internal set; }
}
2019-09-14 04:35:42 +00:00
}