EF6 linq to sql 创建模型时无法使用上下文
EF6 linq to sql The context cannot be used while the model is being created
我必须在我的申请中 System.Timers.Timer。这些计时器的间隔是 1000 和 120000。每次它们滴答时,它们都会将一些实体保存到数据库中。
但有时我的代码中会出现这个错误;正在创建模型时无法使用上下文 created.This 如果在 OnModelCreating 方法内部使用上下文或者如果多个线程同时访问同一上下文实例,则可能会抛出异常。请注意,不保证 DbContext 和相关 类 的实例成员是线程安全的。
这是我的代码:
using ACTMULTILib;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace RenderingPlcScanner
{
class Program
{
[DllImport("kernel32.dll")]
static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
const int SW_HIDE = 0;
const int SW_SHOW = 5;
private System.Timers.Timer timer1 = new System.Timers.Timer();
private System.Timers.Timer timer2 = new System.Timers.Timer();
private GEOTEKRENDERINGEntities grEntities = new GEOTEKRENDERINGEntities();
private ActEasyIF plc = new ActEasyIF();
private bool isUpToDate = true;
private StreamWriter writer;
public Program()
{
grEntities.Database.Connection.Open();
timer1.Interval = 1000;
timer1.Elapsed += timer1_Elapsed;
timer2.Interval = 120000;
timer2.Elapsed += timer2_Elapsed;
....
if (plc.Open() == 0)
{
timer1.Start();
timer2.Start();
}
....
Console.ReadLine();
}
void timer2_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
.....
.....
tblSicakSu tSicakSu = new tblSicakSu();
tSicakSu.Seviye = Math.Truncate(seviye * 100) / 100;
tSicakSu.Sicaklik = Math.Truncate(sicaklik * 100) / 100;
tSicakSu.Tuketim = tuketim[0];
tSicakSu.Zaman = DateTime.Now;
grEntities.tblSicakSu.Add(tSicakSu);
grEntities.SaveChanges();
}
void timer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
timer1.Stop();
try
{
......
DateTime amin = now.AddMinutes(1);
short[] set = new short[3];
plc.ReadDeviceBlock2("D5010", 3, out set[0]);
//Console.WriteLine(amin.ToString() + " - " + set[0] + "/" + set[1]);
if (amin.Hour == set[0] && amin.Minute == set[1] && !tuketimAlindi)
{
tuketimAlindi = true;
short[] tuketim = new short[5];
plc.ReadDeviceBlock2("D3013", 5, out tuketim[0]);
tblTuketim tTuketim = new tblTuketim();
tTuketim.Zaman = DateTime.Now;
tTuketim.YumusakSu = tuketim[0];
tTuketim.DonusSu = tuketim[2];
tTuketim.SicakSu = tuketim[4];
grEntities.tblTuketim.Add(tTuketim);
grEntities.SaveChanges();
//Console.WriteLine("Tüketim alındı");
}
else if (amin.Minute != set[1])
{
tuketimAlindi = false;
}
short[] data = new short[1];
plc.ReadDeviceBlock2("D4300", 1, out data[0]);
if (data[0] == 0)
{
short[] sayac = new short[1];
plc.ReadDeviceBlock2("D14000", 1, out sayac[0]);
//Console.WriteLine(sayac[0]);
if (sayac[0] > 0)
{
short[] datablock = new short[10];
plc.ReadDeviceBlock2("D15000", 10, out datablock[0]);
short uretimID = datablock[0];
short kazanNo = datablock[1];
short malzeme_kodu = datablock[2];
short malzeme_miktari = datablock[3];
short yil = datablock[4];
short ay = datablock[5];
short gun = datablock[6];
short saat = datablock[7];
short dakika = datablock[8];
short saniye = datablock[9];
var vUretim = (from uretim in grEntities.tblUretim where uretim.PartiNo == uretimID select uretim).ToList();
if (vUretim.Count == 0)
{
tblUretim tUretim = new tblUretim();
tUretim.PartiNo = uretimID;
tUretim.KazanNo = kazanNo;
....
......
grEntities.tblUretim.Add(tUretim);
grEntities.SaveChanges();
short[] value = new short[1];
value[0] = 1;
plc.WriteDeviceBlock2("D4300", 1, ref value[0]);
}
else if (vUretim.Count == 1)
{
tblUretim tUretim = vUretim[0];
....
short[] partiTavukUnuMiktari = new short[1];
.....
grEntities.SaveChanges();
short[] value = new short[1];
value[0] = 1;
plc.WriteDeviceBlock2("D4300", 1, ref value[0]);
}
}
}
}
catch(Exception ex)
{
writer.WriteLine("----------------------------------Error (" + DateTime.Now.ToString() + ") ---------------------------------------------------");
writer.WriteLine(ex.Message + " : " + ex.StackTrace);
writer.WriteLine("-----------------------------------------------------------------------------------------------------------------------------");
writer.Flush();
//Console.WriteLine(ex.Message + " " + ex.StackTrace);
}
timer1.Start();
}
static void Main(string[] args)
{
new Program();
}
}
}
发生这种情况是因为计时器导致多个线程访问上下文的同一个实例 class,并且当第二个线程尝试使用 class 时,它仍在忙于尝试创建模型。
您有几个选项可以纠正。我认为最简单的方法是在应用程序或表单加载时禁用第二个计时器,并且仅在第一个计时器代码的第一次迭代具有 运行.
后才启用它
或者,您可以让每个计时器使用其自己的上下文实例。
或者您可以捕获异常并退出该方法,并等到下一次使用上下文对象。
我必须在我的申请中 System.Timers.Timer。这些计时器的间隔是 1000 和 120000。每次它们滴答时,它们都会将一些实体保存到数据库中。
但有时我的代码中会出现这个错误;正在创建模型时无法使用上下文 created.This 如果在 OnModelCreating 方法内部使用上下文或者如果多个线程同时访问同一上下文实例,则可能会抛出异常。请注意,不保证 DbContext 和相关 类 的实例成员是线程安全的。
这是我的代码:
using ACTMULTILib;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace RenderingPlcScanner
{
class Program
{
[DllImport("kernel32.dll")]
static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
const int SW_HIDE = 0;
const int SW_SHOW = 5;
private System.Timers.Timer timer1 = new System.Timers.Timer();
private System.Timers.Timer timer2 = new System.Timers.Timer();
private GEOTEKRENDERINGEntities grEntities = new GEOTEKRENDERINGEntities();
private ActEasyIF plc = new ActEasyIF();
private bool isUpToDate = true;
private StreamWriter writer;
public Program()
{
grEntities.Database.Connection.Open();
timer1.Interval = 1000;
timer1.Elapsed += timer1_Elapsed;
timer2.Interval = 120000;
timer2.Elapsed += timer2_Elapsed;
....
if (plc.Open() == 0)
{
timer1.Start();
timer2.Start();
}
....
Console.ReadLine();
}
void timer2_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
.....
.....
tblSicakSu tSicakSu = new tblSicakSu();
tSicakSu.Seviye = Math.Truncate(seviye * 100) / 100;
tSicakSu.Sicaklik = Math.Truncate(sicaklik * 100) / 100;
tSicakSu.Tuketim = tuketim[0];
tSicakSu.Zaman = DateTime.Now;
grEntities.tblSicakSu.Add(tSicakSu);
grEntities.SaveChanges();
}
void timer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
timer1.Stop();
try
{
......
DateTime amin = now.AddMinutes(1);
short[] set = new short[3];
plc.ReadDeviceBlock2("D5010", 3, out set[0]);
//Console.WriteLine(amin.ToString() + " - " + set[0] + "/" + set[1]);
if (amin.Hour == set[0] && amin.Minute == set[1] && !tuketimAlindi)
{
tuketimAlindi = true;
short[] tuketim = new short[5];
plc.ReadDeviceBlock2("D3013", 5, out tuketim[0]);
tblTuketim tTuketim = new tblTuketim();
tTuketim.Zaman = DateTime.Now;
tTuketim.YumusakSu = tuketim[0];
tTuketim.DonusSu = tuketim[2];
tTuketim.SicakSu = tuketim[4];
grEntities.tblTuketim.Add(tTuketim);
grEntities.SaveChanges();
//Console.WriteLine("Tüketim alındı");
}
else if (amin.Minute != set[1])
{
tuketimAlindi = false;
}
short[] data = new short[1];
plc.ReadDeviceBlock2("D4300", 1, out data[0]);
if (data[0] == 0)
{
short[] sayac = new short[1];
plc.ReadDeviceBlock2("D14000", 1, out sayac[0]);
//Console.WriteLine(sayac[0]);
if (sayac[0] > 0)
{
short[] datablock = new short[10];
plc.ReadDeviceBlock2("D15000", 10, out datablock[0]);
short uretimID = datablock[0];
short kazanNo = datablock[1];
short malzeme_kodu = datablock[2];
short malzeme_miktari = datablock[3];
short yil = datablock[4];
short ay = datablock[5];
short gun = datablock[6];
short saat = datablock[7];
short dakika = datablock[8];
short saniye = datablock[9];
var vUretim = (from uretim in grEntities.tblUretim where uretim.PartiNo == uretimID select uretim).ToList();
if (vUretim.Count == 0)
{
tblUretim tUretim = new tblUretim();
tUretim.PartiNo = uretimID;
tUretim.KazanNo = kazanNo;
....
......
grEntities.tblUretim.Add(tUretim);
grEntities.SaveChanges();
short[] value = new short[1];
value[0] = 1;
plc.WriteDeviceBlock2("D4300", 1, ref value[0]);
}
else if (vUretim.Count == 1)
{
tblUretim tUretim = vUretim[0];
....
short[] partiTavukUnuMiktari = new short[1];
.....
grEntities.SaveChanges();
short[] value = new short[1];
value[0] = 1;
plc.WriteDeviceBlock2("D4300", 1, ref value[0]);
}
}
}
}
catch(Exception ex)
{
writer.WriteLine("----------------------------------Error (" + DateTime.Now.ToString() + ") ---------------------------------------------------");
writer.WriteLine(ex.Message + " : " + ex.StackTrace);
writer.WriteLine("-----------------------------------------------------------------------------------------------------------------------------");
writer.Flush();
//Console.WriteLine(ex.Message + " " + ex.StackTrace);
}
timer1.Start();
}
static void Main(string[] args)
{
new Program();
}
}
}
发生这种情况是因为计时器导致多个线程访问上下文的同一个实例 class,并且当第二个线程尝试使用 class 时,它仍在忙于尝试创建模型。
您有几个选项可以纠正。我认为最简单的方法是在应用程序或表单加载时禁用第二个计时器,并且仅在第一个计时器代码的第一次迭代具有 运行.
后才启用它或者,您可以让每个计时器使用其自己的上下文实例。
或者您可以捕获异常并退出该方法,并等到下一次使用上下文对象。