2019-07-22 22:17:46 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Concurrent;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
2019-11-05 04:14:31 +00:00
|
|
|
|
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;
|
|
|
|
|
|
2019-11-05 04:14:31 +00:00
|
|
|
|
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
|
|
|
|
|
2019-11-05 04:14:31 +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-11-05 04:14:31 +00:00
|
|
|
|
{
|
2019-10-20 11:26:42 +00:00
|
|
|
|
CustomReportFn(progress, msg);
|
2019-11-05 04:14:31 +00:00
|
|
|
|
}
|
2019-10-20 11:26:42 +00:00
|
|
|
|
else
|
2019-11-05 04:14:31 +00:00
|
|
|
|
{
|
|
|
|
|
_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()
|
|
|
|
|
{
|
2019-11-05 04:14:31 +00:00
|
|
|
|
_QueueSize.OnNext((MaxQueueSize, CurrentQueueSize));
|
2019-08-02 23:04:04 +00:00
|
|
|
|
}
|
2019-07-22 22:17:46 +00:00
|
|
|
|
}
|
2019-11-05 04:14:31 +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
|
|
|
|
}
|