C# 使用任务和并行API进行线程同步
我粘贴了4个代码段,尝试使用以下API进行并行化:C# 使用任务和并行API进行线程同步,c#,.net,multithreading,threadpool,C#,.net,Multithreading,Threadpool,我粘贴了4个代码段,尝试使用以下API进行并行化: Parallel.ForEach Parallel.Invoke Task.Run Task.Factory.StartNew 问题试图并行化,这样有两个for循环,内部循环和外部循环,对于外部循环的每次执行,内部循环中的所有内容都应该并行执行 我可以使用Parallel使其工作。ForEach和所有其他方法导致内部计数器出现异常,该值超过了数组索引,而在我看来,情况应该不是这样。此外,索引还以一个更高的值错过目标,例如,当索引的大小为500
Parallel.ForEach
Parallel.Invoke
Task.Run
Task.Factory.StartNew
问题试图并行化,这样有两个for循环,内部循环和外部循环,对于外部循环的每次执行,内部循环中的所有内容都应该并行执行
我可以使用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);
}
}
}
}
使用系统;
使用System.Collections.Generic;
使用系统线程;
使用System.Threading.Tasks;
命名空间测试线程
{
类元素
{
公共价值;
公共内部外部值;
公共元素(int-innerValue、int-outerValue)
{
this.innerValue=innerValue;
this.outerValue=outerValue;
}
}
班级计划
{
私有静态int threadingCounter=0;
专用静态内部计数器=500;
专用静态int outerCounter=1000;
私有静态int[,]inOut;
私有静态整数命中率=0;
私有静态int exceptionCount=0;
私有静态列表innerCount=新列表();
静态void Main(字符串[]参数)
{
inOut=新的int[内部计数器,外部计数器];
程序myProgram=新程序();
对于(int-iCount=0;iCount
{
ThreadCall(新元素(内部、外部));
}
);
WriteLine(“等待后释放的主线程…”);
Console.WriteLine(“命中率::”+命中率);
Console.WriteLine(“异常计数::”+异常计数);
如果(螺纹计数器!=0)
Console.WriteLine(“线程计数器后内循环::”+线程计数器);
}
}
捕获(例外情况除外)
{
Console.WriteLine(“异常::”+ex.Message);
}
最后
{
if(innerCount!=null)
innerCount=null;
}
}
公共void线程调用(对象状态)
{
尝试
{
联锁。增量(参考命中计数);
元素localElement=(元素)状态;
int localInner=localElement.innerValue;
int localOuter=localElement.outerValue;
int finalValue=inOut[localInner,localOuter];
}
捕获(例外情况除外)
{
Console.WriteLine(“异常::”+ex.Message);
}
}
}
}
Parallel.Invoke(由于数组超出索引值而失败,尝试获取内部索引-500)
使用系统;
使用System.Collections.Generic;
使用系统线程;
使用System.Threading.Tasks;
命名空间测试线程
{
///
///
///
类元素
{
公共价值;
公共内部外部值;
公共元素(int-innerValue、int-outerValue)
{
this.innerValue=innerValue;
this.outerValue=outerValue;
}
}
///
///
///
班级计划
{
专用静态内部计数器=500;
专用静态int outerCounter=1000;
私有静态int[,]inOut;
私有静态整数命中率=0;
私有静态int exceptionCount=0;
私有静态列表alSync=新列表();
///
///
///
///
静态void Main(字符串[]参数)
{
inOut=新的int[内部计数器,外部计数器];
程序myProgram=新程序();
尝试
{
for(int-outer=0;outermyProgram.ThreadCall(新元素(内部、外部));
Parallel.Invoke(alSync.ToArray());
alSync.Clear();
WriteLine(“等待后释放的主线程…”);
Console.WriteLine(“命中率::”+命中率);
Console.WriteLine(“异常计数::”+异常计数);
}
}
捕获(例外情况除外)
{
Console.WriteLine(“异常::”+ex.Message);
}
最后
{
如果(alSync!=null)
alSync=null;
}
}
///
///
///
///
公共void线程调用(对象状态)
{
尝试
{
联锁。增量(参考命中计数);
元素localElement=(元素)状态;
int localInner=localElement.innerValue;
int localOuter=localElement.outerValue;
int finalValue=inOut[localInner,localOuter];
}
捕获(例外情况除外)
{
联锁增量(参考例外计数);
Console.WriteLine(“异常::”+ex.Message);
}
}
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);
}
}
}
}
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);
}
}
}
}
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);
}
}
}
}
var ui = TaskScheduler.FromCurrentSynchronizationContext();
someList
.ForEach(f => Task.Factory.StartNew(() =>
{
// do stuff
})
.ContinueWith(task =>
{
if (task.IsCompleted)
{
// update UI
// called after each task above completes
}
}, ui));
for (int inner = 0; inner < innerCounter; inner++)
tlSync.Add(Task.Factory.StartNew(() => myProgram.ThreadCall(new Elements(inner, outer))));
for (int inner = 0; inner < innerCounter; inner++) {
var nInner = inner;
var nOuter = outer;
tlSync.Add(Task.Factory.StartNew(() => myProgram.ThreadCall(new Elements(nInner, nOuter))));
}