2022-06-27 13:30:35 +08:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading;
|
|
|
|
|
using System.Collections.Concurrent;
|
|
|
|
|
|
|
|
|
|
namespace RageCoop.Core
|
|
|
|
|
{
|
|
|
|
|
public class Worker:IDisposable
|
|
|
|
|
{
|
|
|
|
|
private SemaphoreSlim _semaphoreSlim;
|
|
|
|
|
private Thread _workerThread;
|
|
|
|
|
private bool _stopping=false;
|
|
|
|
|
public string Name { get; set; }
|
|
|
|
|
public bool IsBusy { get;private set; }
|
2022-06-30 09:28:13 +08:00
|
|
|
|
internal Worker(string name,Logger logger,int maxJobs = Int32.MaxValue)
|
2022-06-27 13:30:35 +08:00
|
|
|
|
{
|
|
|
|
|
Name = name;
|
2022-06-30 09:28:13 +08:00
|
|
|
|
_semaphoreSlim = new SemaphoreSlim(0,maxJobs);
|
2022-06-27 13:30:35 +08:00
|
|
|
|
_workerThread=new Thread(() =>
|
|
|
|
|
{
|
|
|
|
|
while (!_stopping)
|
|
|
|
|
{
|
|
|
|
|
IsBusy=false;
|
|
|
|
|
_semaphoreSlim.Wait();
|
|
|
|
|
if(Jobs.TryDequeue(out var job))
|
|
|
|
|
{
|
|
|
|
|
IsBusy=true;
|
2022-06-30 09:28:13 +08:00
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
job.Invoke();
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
logger.Error("Error occurred when executing queued job:");
|
|
|
|
|
logger.Error(ex);
|
|
|
|
|
}
|
2022-06-27 13:30:35 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
throw new InvalidOperationException("Hmm... that's unexpected.");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
IsBusy=false;
|
|
|
|
|
});
|
|
|
|
|
_workerThread.Start();
|
|
|
|
|
}
|
2022-06-30 09:28:13 +08:00
|
|
|
|
public void QueueJob(Action work)
|
2022-06-27 13:30:35 +08:00
|
|
|
|
{
|
|
|
|
|
Jobs.Enqueue(work);
|
|
|
|
|
_semaphoreSlim.Release();
|
|
|
|
|
}
|
|
|
|
|
public void Stop()
|
|
|
|
|
{
|
|
|
|
|
_stopping=true;
|
2022-06-30 09:28:13 +08:00
|
|
|
|
QueueJob(() => { });
|
2022-06-27 13:30:35 +08:00
|
|
|
|
if (_workerThread.IsAlive)
|
|
|
|
|
{
|
|
|
|
|
_workerThread.Join();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
|
|
|
|
Stop();
|
|
|
|
|
_semaphoreSlim.Dispose();
|
|
|
|
|
}
|
|
|
|
|
private ConcurrentQueue<Action> Jobs=new ConcurrentQueue<Action>();
|
|
|
|
|
}
|
|
|
|
|
}
|