C#CPU多核任务处理

        public void WorkOnMultiCore(TArgument aArgument, System.Func aGetCount, System.Action aBeforeStart, System.Action>> aDoWork, System.Action, IBackgroundThreadWorker>> aProgressChanged, System.Action aWorkCompleted)
        {
            long tCount = aGetCount(aArgument);

            if (tCount == 0)
            {
                return;
            }

            int tThreads = System.Environment.ProcessorCount * 2;

            long tSize = tCount / tThreads;

            System.Collections.Generic.List tIndexRanges = new System.Collections.Generic.List();

            if (tSize == 0 || tCount <= 2 * tThreads)
            {
                tIndexRanges.Add(new IndexRange(0, tCount - 1));
            }
            else
            {
                long tLastValue = 0;
                for (int tThreadIndex = 0; tThreadIndex < tThreads - 1; tThreadIndex++)
                {
                    long tFromValue = tThreadIndex * tSize;

                    long tToValue = (tThreadIndex + 1) * tSize - 1;
                    tLastValue = tToValue;

                    IndexRange tIndexRange = new IndexRange(tFromValue, tToValue);

                    tIndexRanges.Add(tIndexRange);
                }

                // Add the last range index
                if (tLastValue + 1 < tCount)
                {
                    tIndexRanges.Add(new IndexRange(tLastValue + 1, tCount - 1));
                }
            }

            int tCounter = tIndexRanges.Count;

            this._Totals = new System.Collections.Generic.SortedList();
            this._Currents = new System.Collections.Generic.SortedList();
            this._AssertManualResetEvent = new System.Threading.ManualResetEvent(true);

            System.Threading.AutoResetEvent tSignal = new System.Threading.AutoResetEvent(false);

            foreach (IndexRange tIndexRange in tIndexRanges)
            {
                System.Guid tThreadGuid = System.Guid.NewGuid();

                MultiCoreArgument tMultiCoreArgument = new MultiCoreArgument(aArgument, tIndexRange, tThreadGuid);

                BackgroundThreadWorker, object> tBackgroundThreadWorker = BackgroundThreadWorker, object>.Prepare(
                    tMultiCoreArgument,
                    null,
                    (aArgumentForWorker, aWorker) =>
                    {
                        try
                        {
                            if (aDoWork != null)
                            {
                                MultiCoreBackgroundThreadInsiderWorker tMultiCoreBackgroundThreadWorker = new MultiCoreBackgroundThreadInsiderWorker(aArgumentForWorker.ThreadGuid, aWorker);
                                aDoWork(tMultiCoreArgument.Argument, tMultiCoreArgument.IndexRange, tMultiCoreBackgroundThreadWorker);
                            }

                            if (System.Threading.Interlocked.Decrement(ref tCounter) == 0)
                            {
                                tSignal.Set();
                            }
                        }
                        catch (System.Exception e)
                        {
                            Western.Objects.Common.Message(new Western.Common.SystemStackPosition(this.GetType(), "WorkOnMultiCore+DoWork"), new Western.Common.SystemStack(e));
                        }
                        return null;
                    },
                    (aProgress, aWorker) =>
                    {
                        if (aProgressChanged != null)
                        {
                            try
                            {
                                this._AssertManualResetEvent.WaitOne();
                                this._AssertManualResetEvent.Reset();

                                MultiCoreReport tMultiCoreReport = aProgress.UserState;

                                this._Totals[tMultiCoreReport.ReportGuid] = aProgress.Total;
                                this._Currents[tMultiCoreReport.ReportGuid] = aProgress.Current;

                                double tTotal = 0;
                                double tCurrent = 0;

                                foreach (double tValue in this._Totals.Values)
                                {
                                    tTotal += tValue;
                                }

                                foreach (double tValue in this._Currents.Values)
                                {
                                    tCurrent += tValue;
                                }

                                this._AssertManualResetEvent.Set();

                                aProgressChanged(new ProgressChangedEventArgs(tCurrent, tTotal, aProgress.Message, aProgress.UserState.Value), aWorker);
                            }
                            catch (System.Exception e)
                            {
                                Western.Objects.Common.Message(new Western.Common.SystemStackPosition(this.GetType(), "WorkOnMultiCore+Progress"), new Western.Common.SystemStack(e));
                            }
                        }
                    },
                    (aResult, aWorker) =>
                    {
                        if (aWorkCompleted != null)
                        {
                            aWorkCompleted();
                        }
                    }
                );

                this._BackgroundWorkers.Add(tThreadGuid, tBackgroundThreadWorker);
            }

            if (aBeforeStart != null)
            {
                aBeforeStart();
            }

            foreach (BackgroundThreadWorker, object> tBackgroundThreadWorker in this._BackgroundWorkers.Values)
            {
                System.Threading.ThreadPool.QueueUserWorkItem((aParameter) =>
                {
                    ((BackgroundThreadWorker, object>)aParameter).Start();

                }, tBackgroundThreadWorker);
            }

            tSignal.WaitOne();
        }

你可能感兴趣的:(.net技术交流)