コード例 #1
0
        public void ChangeNumberThreads(int countThreads)
        {
            lock (locker)
            {
                if (countThreads == ThreadsCount)
                {
                    return;
                }
                ThreadsCount = countThreads;

                if (threads != null)
                {
                    foreach (var thread in threads)
                    {
                        thread?.Abort();
                    }

                    while (!FreeThreads.IsEmpty)
                    {
                        FreeThreads.TryDequeue(out _);
                    }
                }

                if (countThreads > 0)
                {
                    threads = new ThreadUnit[ThreadsCount];
                    for (var i = 0; i < ThreadsCount; i++)
                    {
                        threads[i] = new ThreadUnit($"Thread #{i}", i);
                        FreeThreads.Enqueue(threads[i]);
                    }
                }
                else
                {
                    threads = null;
                }
            }
        }
コード例 #2
0
        public void Process(object o)
        {
            if (threads == null)
            {
                return;
            }
            if (Interlocked.CompareExchange(ref _lock, 1, 0) == 1)
            {
                return;
            }

            if (ProcessWorking)
            {
                DebugWindow.LogMsg($"WTF {_objectInitWork.GetType()}");
            }

            _objectInitWork = o;
            ProcessWorking  = true;
            spinWait.Reset();

            while (Jobs.TryDequeue(out var j))
            {
                processJobs.Enqueue(j);
            }


            if (ThreadsCount > 1)
            {
                while (processJobs.Count > 0)
                {
                    if (!FreeThreads.IsEmpty)
                    {
                        FreeThreads.TryDequeue(out var freeThread);
                        var job = processJobs.Dequeue();
                        if (!freeThread.AddJob(job))
                        {
                            processJobs.Enqueue(job);
                        }
                        else
                        {
                            if (freeThread.Free)
                            {
                                FreeThreads.Enqueue(freeThread);
                            }
                        }
                    }
                    else
                    {
                        spinWait.SpinOnce();
                        var allThreadsBusy = true;
                        for (int i = 0; i < threads.Length; i++)
                        {
                            var th = threads[i];
                            if (th.Free)
                            {
                                allThreadsBusy = false;
                                FreeThreads.Enqueue(th);
                            }
                        }

                        if (allThreadsBusy)
                        {
                            for (int i = 0; i < threads.Length; i++)
                            {
                                var th            = threads[i];
                                var thWorkingTime = th.WorkingTime;
                                if (thWorkingTime > CriticalWorkTimeMs)
                                {
                                    DebugWindow.LogMsg(
                                        $"Repair thread #{th.Number} with Job1: {th.Job.Name} (C: {th.Job.IsCompleted} F: {th.Job.IsFailed}) && Job2:{th.SecondJob.Name} (C: {th.SecondJob.IsCompleted} F: {th.SecondJob.IsFailed}) Time: {thWorkingTime} > {thWorkingTime >= CriticalWorkTimeMs}",
                                        5);
                                    th.Abort();
                                    BrokenThreads.Add(th);
                                    var newThread = new ThreadUnit($"Repair critical time {th.Number}", th.Number);
                                    threads[th.Number] = newThread;
                                    FreeThreads.Enqueue(newThread);
                                    Thread.Sleep(5);
                                    FailedThreadsCount++;
                                    break;
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                var threadUnit = threads[0];
                while (processJobs.Count > 0)
                {
                    if (threadUnit.Free)
                    {
                        var job = processJobs.Dequeue();
                        threadUnit.AddJob(job);
                    }
                    else
                    {
                        spinWait.SpinOnce();
                        var threadUnitWorkingTime = threadUnit.WorkingTime;
                        if (threadUnitWorkingTime > CriticalWorkTimeMs)
                        {
                            DebugWindow.LogMsg(
                                $"Repair thread #{threadUnit.Number} withreadUnit Job1: {threadUnit.Job.Name} (C: {threadUnit.Job.IsCompleted} F: {threadUnit.Job.IsFailed}) && Job2:{threadUnit.SecondJob.Name} (C: {threadUnit.SecondJob.IsCompleted} F: {threadUnit.SecondJob.IsFailed}) Time: {threadUnitWorkingTime} > {threadUnitWorkingTime >= CriticalWorkTimeMs}",
                                5);
                            threadUnit.Abort();
                            BrokenThreads.Add(threadUnit);
                            threadUnit = new ThreadUnit($"Repair critical time {threadUnit.Number}", threadUnit.Number);
                            Thread.Sleep(5);
                            FailedThreadsCount++;
                        }
                    }
                }
            }

            if (BrokenThreads.Count > 0)
            {
                var criticalWorkTimeMs = CriticalWorkTimeMs * 2;
                for (var index = 0; index < BrokenThreads.Count; index++)
                {
                    var brokenThread = BrokenThreads[index];
                    if (brokenThread == null)
                    {
                        continue;
                    }
                    if (brokenThread.WorkingTime > criticalWorkTimeMs)
                    {
                        brokenThread.ForceAbort();
                        BrokenThreads[index] = null;
                    }
                }

                if (BrokenThreads.AllF(x => x == null))
                {
                    BrokenThreads.Clear();
                }
            }

            Interlocked.CompareExchange(ref _lock, 0, 1);
            ProcessWorking = false;
        }