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 时,它仍在忙于尝试创建模型。

您有几个选项可以纠正。我认为最简单的方法是在应用程序或表单加载时禁用第二个计时器,并且仅在第一个计时器代码的第一次迭代具有 运行.

后才启用它

或者,您可以让每个计时器使用其自己的上下文实例。

或者您可以捕获异常并退出该方法,并等到下一次使用上下文对象。