当我尝试使用方法AddTimeSeriesDefinition(TimeSeries series)
或AddTimeSeriesMetaData(TimeSeriesMetaData tsData)
时遇到问题Parallel.ForEach()
为此挣扎了几个小时,我不敢相信我找不到任何解决方案甚至理论原因。
在我的类Data
中包含我的数据库上下文DBEntity db = new DBEntity()
我有AddTimeSeriesDefinition(TimeSeries series)
和AddTimeSeriesMetaData()
方法:
public class Data : IDisposable
{
private DBEntity db;
public Data()
{
db = new DBEntity();
}
public TimeSeries AddTimeSeriesDefinition(TimeSeries series)
{
var timeSeries = db.TimeSeries.Where(ts => ts.Key1 == series.Key1 )
.Where(ts => ts.Key2 == series.Key2 )
.Where(ts => ts.Key3 == series.Key3 )
.FirstOrDefault();
if ( timeSeries == null )
{
timeSeries = db.TimeSeries.Add(series);
db.SaveChanges();
}
return timeSeries;
}
public void AddTimeSeriesMetaData(TimeSeriesMetaData tsData)
{
var tsd = db.TimeSeriesMetaData.Where(ts => ts.Key1 == tsData.Key1 )
.Where(ts => ts.Key2== tsData.Key2)
.FirstOrDefault();
if (tsd == null)
db.TimeSeriesMetaData.Add(tsData);
else
tsd.Value = tsData.Value;
try
{
db.SaveChanges();
}
catch (Exception ex)
{
Log.Error($"Error occurred (...) Key1:{tsData.Key1} Key2:{tsData.Key2}", ex);
}
}
Dispose()
{...}
}
但是,当我在主类中使用它们时,例如:
private MainClass
{
Data DB { get { value = new Data() } }
...
Parallel.ForEach( // arguments )
{
...
using( var db = DB )
{
db.AddTimeSeriesDefinition(timeSeries);
}
...
}
}
有时,完全随机地在排队时崩溃
db.SaveChanges();
例外:
Violation of PRIMARY KEY constraint 'PK_TimeSeriesMetaDatas'. Cannot insert duplicate key in object 'dbo.TimeSeriesMetaData'. The duplicate key value is ("Key1", "Key2"). The statement has been terminated.
例如,我的 TimeSeriesMetaData
EF 类:
[Table("TimeSeriesMetaData")]
public partial class TimeSeriesMetaData
{
[Key]
[Column(Order = 0)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public string Key1 { get; set; }
[Key]
[Column(Order = 1)]
public string Key2 { get; set; }
[Required]
public string Key3 { get; set; }
}
我读过每次为每个操作创建Entity Framework
DBContext
也应该是线程安全的。如果我总是检查记录是否存在,可能导致此问题的原因是什么?
我将不胜感激任何帮助。
问题是 DbSet 不是 ThreadSafe。您在 Parallel.ForEach 循环中有一个运行条件。您必须锁定对这两种方法的调用。https://msdn.microsoft.com/en-us/library/c5kehkcz.aspx
希望对你有帮助