Я оклейки 4 фрагменты кода, где распараллеливания будет предпринята попытка использовать следующие интерфейсы:синхронизации Thread с помощью задач и параллельных интерфейсов API
Parallel.ForEach
Parallel.Invoke
Task.Run
Task.Factory.StartNew
Проблема пытается распараллелить такие, что Есть два для петель, внутренних и внешних, так и для каждое выполнение внешнего цикла во внутреннем цикле должно выполняться в Parallel.
Я могу заставить его работать с использованием Parallel.ForEach
, а все остальные приводят к исключению, как для внутреннего счетчика, это значение превышает индекс массива, когда, на мой взгляд, этого не должно быть. Также индекс пропускает цель на одно более высокое значение, например, когда размер индекса равен 500, он пытается получить доступ к значению 500, когда в идеале он должен остановиться на 499. Я что-то упускаю. Ниже приведены фрагменты кода, пожалуйста смотрите:
Parallel.ForEach (рабочий)
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace TestThreads
{
class Elements
{
public int innerValue;
public int outerValue;
public Elements(int innerValue, int outerValue)
{
this.innerValue = innerValue;
this.outerValue = outerValue;
}
}
class Program
{
private static int threadingCounter = 0;
private static int innerCounter = 500;
private static int outerCounter = 1000;
private static int[,] inOut;
private static int hitCount = 0;
private static int exceptionCount = 0;
private static List<int> innerCount = new List<int>();
static void Main(string[] args)
{
inOut = new int[innerCounter, outerCounter];
Program myProgram = new Program();
for (int iCount = 0; iCount < innerCounter; iCount++)
innerCount.Add(iCount);
try
{
for (int outer = 0; outer < outerCounter; outer++)
{
Parallel.ForEach<int>(innerCount, inner =>
{
myProgram.ThreadCall(new Elements(inner,outer));
}
);
Console.WriteLine("Main Thread Released Post Wait ...");
Console.WriteLine("Hit Count :: " + hitCount);
Console.WriteLine("Exception Count :: " + exceptionCount);
if (threadingCounter != 0)
Console.WriteLine("Threading Counter post Inner Loop :: " + threadingCounter);
}
}
catch (Exception ex)
{
Console.WriteLine("Exception :: " + ex.Message);
}
finally
{
if (innerCount != null)
innerCount = null;
}
}
public void ThreadCall(object state)
{
try
{
Interlocked.Increment(ref hitCount);
Elements localElement = (Elements)state;
int localInner = localElement.innerValue;
int localOuter = localElement.outerValue;
int finalValue = inOut[localInner, localOuter];
}
catch (Exception ex)
{
Console.WriteLine("Exception :: " + ex.Message);
}
}
}
}
Parallel.Invoke (Failing с массивом из значения индекса, пытается извлечь внутренний индекс - 500)
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace TestThreads
{
/// <summary>
///
/// </summary>
class Elements
{
public int innerValue;
public int outerValue;
public Elements(int innerValue, int outerValue)
{
this.innerValue = innerValue;
this.outerValue = outerValue;
}
}
/// <summary>
///
/// </summary>
class Program
{
private static int innerCounter = 500;
private static int outerCounter = 1000;
private static int[,] inOut;
private static int hitCount = 0;
private static int exceptionCount = 0;
private static List<Action> alSync = new List<Action>();
/// <summary>
///
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
inOut = new int[innerCounter, outerCounter];
Program myProgram = new Program();
try
{
for (int outer = 0; outer < outerCounter; outer++)
{
for (int inner = 0; inner < innerCounter; inner++)
alSync.Add(() => myProgram.ThreadCall(new Elements(inner, outer)));
Parallel.Invoke(alSync.ToArray());
alSync.Clear();
Console.WriteLine("Main Thread Released Post Wait ...");
Console.WriteLine("Hit Count :: " + hitCount);
Console.WriteLine("Exception Count :: " + exceptionCount);
}
}
catch (Exception ex)
{
Console.WriteLine("Exception :: " + ex.Message);
}
finally
{
if (alSync != null)
alSync = null;
}
}
/// <summary>
///
/// </summary>
/// <param name="state"></param>
public void ThreadCall(object state)
{
try
{
Interlocked.Increment(ref hitCount);
Elements localElement = (Elements)state;
int localInner = localElement.innerValue;
int localOuter = localElement.outerValue;
int finalValue = inOut[localInner, localOuter];
}
catch (Exception ex)
{
Interlocked.Increment(ref exceptionCount);
Console.WriteLine("Exception :: " + ex.Message);
}
}
}
}
Task.Run (в противном случае с массивом из значения индекса, пытается извлечь внутренний индекс - 500)
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace TestThreads
{
/// <summary>
///
/// </summary>
class Elements
{
public int innerValue;
public int outerValue;
public Elements(int innerValue, int outerValue)
{
this.innerValue = innerValue;
this.outerValue = outerValue;
}
}
/// <summary>
///
/// </summary>
class Program
{
private static int innerCounter = 500;
private static int outerCounter = 1000;
private static int[,] inOut;
private static int hitCount = 0;
private static int exceptionCount = 0;
private static List<Task> tlSync = new List<Task>();
/// <summary>
///
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
inOut = new int[innerCounter, outerCounter];
Program myProgram = new Program();
try
{
for (int outer = 0; outer < outerCounter; outer++)
{
for (int inner = 0; inner < innerCounter; inner++)
tlSync.Add(Task.Run(() => myProgram.ThreadCall(new Elements(inner, outer))));
Task.WaitAll(tlSync.ToArray());
tlSync.Clear();
Console.WriteLine("Main Thread Released Post Wait ...");
Console.WriteLine("Hit Count :: " + hitCount);
Console.WriteLine("Exception Count :: " + exceptionCount);
}
}
catch (Exception ex)
{
Console.WriteLine("Exception :: " + ex.Message);
}
finally
{
if (tlSync != null)
tlSync = null;
}
}
/// <summary>
///
/// </summary>
/// <param name="state"></param>
public void ThreadCall(object state)
{
try
{
Interlocked.Increment(ref hitCount);
Elements localElement = (Elements)state;
int localInner = localElement.innerValue;
int localOuter = localElement.outerValue;
int finalValue = inOut[localInner, localOuter];
}
catch (Exception ex)
{
Interlocked.Increment(ref exceptionCount);
Console.WriteLine("Exception :: " + ex.Message);
}
}
}
}
Task.Factory.StartNew (В противном случае с массивом из значения индекса, пытается извлечь внутренний индекс - 500)
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace TestThreads
{
/// <summary>
///
/// </summary>
class Elements
{
public int innerValue;
public int outerValue;
public Elements(int innerValue, int outerValue)
{
this.innerValue = innerValue;
this.outerValue = outerValue;
}
}
/// <summary>
///
/// </summary>
class Program
{
private static int innerCounter = 500;
private static int outerCounter = 1000;
private static int[,] inOut;
private static int hitCount = 0;
private static int exceptionCount = 0;
private static List<Task> tlSync = new List<Task>();
/// <summary>
///
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
inOut = new int[innerCounter, outerCounter];
Program myProgram = new Program();
try
{
for (int outer = 0; outer < outerCounter; outer++)
{
for (int inner = 0; inner < innerCounter; inner++)
tlSync.Add(Task.Factory.StartNew(() =>
myProgram.ThreadCall(new Elements(inner, outer))));
Task.WaitAll(tlSync.ToArray());
tlSync.Clear();
Console.WriteLine("Main Thread Released Post Wait ...");
Console.WriteLine("Hit Count :: " + hitCount);
Console.WriteLine("Exception Count :: " + exceptionCount);
}
}
catch (Exception ex)
{
Console.WriteLine("Exception :: " + ex.Message);
}
finally
{
if (tlSync != null)
tlSync = null;
}
}
/// <summary>
///
/// </summary>
/// <param name="state"></param>
public void ThreadCall(object state)
{
try
{
Interlocked.Increment(ref hitCount);
Elements localElement = (Elements)state;
int localInner = localElement.innerValue;
int localOuter = localElement.outerValue;
int finalValue = inOut[localInner, localOuter];
}
catch (Exception ex)
{
Interlocked.Increment(ref exceptionCount);
Console.WriteLine("Exception :: " + ex.Message);
}
}
}
}
Будет использование tlSync? и что делает ThreadCall? – Robert