public void WorkOnMultiCore(TArgument aArgument, System.Func<TArgument, long> aGetCount, System.Action aBeforeStart, System.Action<TArgument, IndexRange, IBackgroundThreadWorker<MultiCoreReport<TReport>>> aDoWork, System.Action<ProgressChangedEventArgs<TReport>, IBackgroundThreadWorker<MultiCoreReport<TReport>>> 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<IndexRange> tIndexRanges = new System.Collections.Generic.List<IndexRange>();
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<System.Guid, double>();
this._Currents = new System.Collections.Generic.SortedList<System.Guid, double>();
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<MultiCoreArgument, MultiCoreReport<TReport>, object> tBackgroundThreadWorker = BackgroundThreadWorker<MultiCoreArgument, MultiCoreReport<TReport>, 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<TReport> 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<TReport>(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<MultiCoreArgument, MultiCoreReport<TReport>, object> tBackgroundThreadWorker in this._BackgroundWorkers.Values)
{
System.Threading.ThreadPool.QueueUserWorkItem((aParameter) =>
{
((BackgroundThreadWorker<MultiCoreArgument, MultiCoreReport<TReport>, object>)aParameter).Start();
}, tBackgroundThreadWorker);
}
tSignal.WaitOne();
}
C#CPU多核任务处理
最新推荐文章于 2024-07-05 17:59:22 发布