using
System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
namespace ParallelTest1
{
public class CalcTask
{
public event EventHandler < TaskItemEventArgs > OnTaskFinish;
public void ExecuteTasks()
{
int icount = 100 ;
List < Task > items = new List < Task > (icount);
PInitializeTask(items, icount);
Console.WriteLine(items.Count);
List < Task > items2 = new List < Task > ();
SInitializeTask(items2, icount);
Console.WriteLine(items2.Count);
Console.ReadKey();
}
private void PInitializeTask(List < Task > items, int iCount)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
Parallel.For( 0 , iCount, new ParallelOptions()
{
}, i =>
{
lock (items) // 如果不加锁,观察最终集合的个数?
{
items.Add( new Task()
{
Source = i,
Dest = i + i,
});
// if (items.Count == iCount)
OnTaskFinish( this , new TaskItemEventArgs()
{
ThreadId = Thread.CurrentThread.ManagedThreadId,
Data = items,
});
}
});
stopwatch.Stop();
Console.WriteLine( " Parallel loop time in milliseconds: {0} " , stopwatch.ElapsedMilliseconds);
}
private void SInitializeTask(List < Task > items, int iCount)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
for ( int i = 0 ;i < iCount;i ++ )
{
items.Add( new Task()
{
Source = i,
Dest = i + i,
});
OnTaskFinish( this , new TaskItemEventArgs()
{
ThreadId = Thread.CurrentThread.ManagedThreadId,
Data = items,
});
}
stopwatch.Stop();
Console.WriteLine( " Sequential loop time in milliseconds: {0} " , stopwatch.ElapsedMilliseconds);
}
}
public class Task
{
public int Source { get ; set ; }
public int Dest { get ; set ; }
public override string ToString()
{
return string .Format( " {0}-{1} " , this .Source, this .Dest);
}
}
public class TaskItemEventArgs:EventArgs
{
public int ThreadId{ get ; set ;}
public object Data{ get ; set ;}
}
}
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
namespace ParallelTest1
{
public class CalcTask
{
public event EventHandler < TaskItemEventArgs > OnTaskFinish;
public void ExecuteTasks()
{
int icount = 100 ;
List < Task > items = new List < Task > (icount);
PInitializeTask(items, icount);
Console.WriteLine(items.Count);
List < Task > items2 = new List < Task > ();
SInitializeTask(items2, icount);
Console.WriteLine(items2.Count);
Console.ReadKey();
}
private void PInitializeTask(List < Task > items, int iCount)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
Parallel.For( 0 , iCount, new ParallelOptions()
{
}, i =>
{
lock (items) // 如果不加锁,观察最终集合的个数?
{
items.Add( new Task()
{
Source = i,
Dest = i + i,
});
// if (items.Count == iCount)
OnTaskFinish( this , new TaskItemEventArgs()
{
ThreadId = Thread.CurrentThread.ManagedThreadId,
Data = items,
});
}
});
stopwatch.Stop();
Console.WriteLine( " Parallel loop time in milliseconds: {0} " , stopwatch.ElapsedMilliseconds);
}
private void SInitializeTask(List < Task > items, int iCount)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
for ( int i = 0 ;i < iCount;i ++ )
{
items.Add( new Task()
{
Source = i,
Dest = i + i,
});
OnTaskFinish( this , new TaskItemEventArgs()
{
ThreadId = Thread.CurrentThread.ManagedThreadId,
Data = items,
});
}
stopwatch.Stop();
Console.WriteLine( " Sequential loop time in milliseconds: {0} " , stopwatch.ElapsedMilliseconds);
}
}
public class Task
{
public int Source { get ; set ; }
public int Dest { get ; set ; }
public override string ToString()
{
return string .Format( " {0}-{1} " , this .Source, this .Dest);
}
}
public class TaskItemEventArgs:EventArgs
{
public int ThreadId{ get ; set ;}
public object Data{ get ; set ;}
}
}
static
void
Main(
string
[] args)
{
Console.WriteLine( " Processor Count: " + Environment.ProcessorCount);
CalcTask task1 = new CalcTask();
task1.OnTaskFinish += new EventHandler < TaskItemEventArgs > ((sender, e) =>
{
Console.WriteLine( string .Format( " Finish:{0}-{1} " , e.ThreadId, (e.Data as List < Task > ).Count));
});
task1.ExecuteTasks();
}
{
Console.WriteLine( " Processor Count: " + Environment.ProcessorCount);
CalcTask task1 = new CalcTask();
task1.OnTaskFinish += new EventHandler < TaskItemEventArgs > ((sender, e) =>
{
Console.WriteLine( string .Format( " Finish:{0}-{1} " , e.ThreadId, (e.Data as List < Task > ).Count));
});
task1.ExecuteTasks();
}
在上述代码中,我测试的结果规律如下:
如果并行中,不加lock,如果是向集合填充100万个对象 ,那么并行代码 执行完毕后,那个集合的数目永远都是小于100万,我的结果显示是80多万。。。。估计中间发生冲突导致部分的项添加不成功,但是.net并没有报错,这样很容易让我们中招。所以用一般集合时需要小心,这里也证实了一般的集合List<T>并不是线程安全的。。。
后来我换成System.Collections.Concurrent.ConcurrentDictionary<int, Task>试了下,发现不用加lock,结果也是正确的,所以大家在并行运算中记得多使用这个哈希结构。。。但是线程安全的。