C# 为了表明第一个线程确实写入了ScheduleConfiguration?

C# 为了表明第一个线程确实写入了ScheduleConfiguration?,c#,multithreading,static-members,C#,Multithreading,Static Members,,首先,没有迹象表明您在任何地方有任何内存障碍,可以确保任何写入都完全“刷新”到主内存,读操作进入主内存,而不是使用寄存器等。基本上,在没有某种保护的情况下,不应该使用线程之间共享的字段 从某种程度上说,这是一个理论上的风险——不清楚这是否是问题所在,尽管这确实是一个真正的可能性。我强烈怀疑还有另一个问题,但在您没有向我们展示的代码中。您是否有诊断来指示第一个线程确实写入了ScheduleConfiguration?您是否可以添加代码,在其中操作DataTable?您没有发布与数据库通信的代码,

,首先,没有迹象表明您在任何地方有任何内存障碍,可以确保任何写入都完全“刷新”到主内存,读操作进入主内存,而不是使用寄存器等。基本上,在没有某种保护的情况下,不应该使用线程之间共享的字段


从某种程度上说,这是一个理论上的风险——不清楚这是否是问题所在,尽管这确实是一个真正的可能性。我强烈怀疑还有另一个问题,但在您没有向我们展示的代码中。您是否有诊断来指示第一个线程确实写入了
ScheduleConfiguration

您是否可以添加代码,在其中操作DataTable?您没有发布与数据库通信的代码,我认为问题就在那里,因为如果一个方法更新数据库中的数据,而另一个方法稍后从数据库中读取数据,那么无论变量是否为静态变量,都应该没有问题。
ProcessScheduledUpdates
是从windows服务调用的,[2]是由线程交叉的。。。这有什么区别吗???(这可能是一个非常愚蠢的问题,但事情对我不起作用:()你能在操作DataTable的地方添加代码吗?我想,你没有发布与数据库通信的代码,问题就在那里,因为如果一个方法更新数据库中的数据,而另一个方法稍后从数据库中读取数据,那么应该没有问题,不管你的变量是静态的还是非静态的
ProcessScheduledUpdates
是从windows服务调用的,[2]被线程交叉…这有什么区别吗??(这可能是一个非常愚蠢的问题,但事情对我不起作用:()嗯,我只是故意没有检查任何内存障碍。我想在调试时进行检查…假设一切都是安全的…@Umer:基本上,这不安全。在更改共享变量时,你应该使用锁定或其他类型的内存障碍。但我猜这实际上是你的
UpdateSchedulingRefTable
方法ply没有进入最后设置变量的部分-它必须满足各种条件才能到达那里。是否有可能即使在调试时,也会出现这样的问题(我假设没有,因为每个步骤都在我们的控件上执行)???@Umer:可能不是-我强烈怀疑这是另一个问题,例如,找不到任何表。我只是故意没有检查任何内存障碍。我想在调试时检查…假设一切都是安全的…@Umer:基本上不安全。在更改sha时,应该使用锁定或其他类型的内存障碍红色变量。但我猜实际上你的
UpdateSchedulingRefTable
方法根本没有进入到设置变量的部分——它必须满足各种条件才能到达那里。是否有可能即使在调试时,也会出现这样的问题(我假设没有,因为每个步骤都是在我们的控件上执行的)??@Umer:可能不是-我强烈怀疑这是另一个问题,例如,没有找到表。
public class ScheduledUpdater
{
    private static readonly object lockingObject = new object();
    private static Queue<int> PendingIDs = new Queue<int>();
    private static bool UpdateThreadRunning = false;
    private static bool IsGetAndSaveScheduledUpdateRunning = false;
    private static DataTable ScheduleConfiguration;
    private static Thread updateRefTableThread;
    private static Thread threadToGetAndSaveScheduledUpdate;
    public static void ProcessScheduledUpdates(int ID)
    {
        //do some stuff
        // if ( updateRefTableThread not already running)
        // execute updateRefTableThread = new Thread(new ThreadStart(UpdateSchedulingRefTableInThrear));
        // execute updateRefTableThread.Start();
        //do  some stuff
        ***[1]***
        GetAndSaveScheduledUpdate(ID)
    }
    private static void UpdateSchedulingRefTableInThrear()
    {
        //if(updateRefTableThread==true)
        //    return;
        // updateRefTableThread = true
        do{
        UpdateSchedulingRefTable(); 
        Thread.sleep(800000);
        }while(updateRefTableThread);
        //updateRefTableThread = false;
    }
    public static void UpdateSchedulingRefTable()
    { 
        // read DB and update ScheduleConfiguration 
        string query = " SELECT ID,TimeToSendEmail FROM TBLa WHERE MODE = 'WebServiceOrder' AND BDELETE = false ";
        clsCommandBuilder commandBuilder = new clsCommandBuilder();
        DataSet ds = commandBuilder.GetDataSet(query);
        if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
        {
            List<string> lstIDs = new List<string>();
            for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
            {
                lstIDs.Add(ds.Tables[0].Rows[i]["ID"].ToString());
                if (LastEmailSend.Contains(ds.Tables[0].Rows[i]["ID"].ToString()))
                    LastEmailSend[ds.Tables[0].Rows[i]["ID"].ToString()] = ds.Tables[0].Rows[i]["TimeToSendEmail"].ToString();
                else
                    LastEmailSend.Add(ds.Tables[0].Rows[i]["ID"].ToString(), ds.Tables[0].Rows[i]["TimeToSendEmail"].ToString());
            }
            if (lstIDs.Count > 0)
            {
                string Ids = string.Join(",", lstIDs.ToArray()).Trim(',');
                dhDBNames dbNames = new dhDBNames();
                dbNames.Default_DB_Name = dbNames.ControlDB;
                dhGeneralPurpose dhGeneral = new dhGeneralPurpose();
                dhGeneral.StringDH = Ids;
                DataSet result = commandBuilder.GetDataSet(dbNames, (object)dhGeneral, "xmlGetConfigurations");
                if (result != null && result.Tables.Count > 0)
                {
                    ***[2]***
                    Monitor.Enter(lockingObject);
                    if (ScheduleConfiguration != null)
                        ScheduleConfiguration.Clear();
                    ScheduleConfiguration = result.Tables[0];
                    Monitor.Exit(lockingObject);
                }
            }
        }
    }
    public static void GetAndSaveScheduledUpdate(int ID)
    {
        ***[3]***
        //use ScheduleConfiguration 
        Monitor.Enter(lockingObject);
        if (ScheduleConfiguration == null)
        {
            UpdateSchedulingRefTable();
            Monitor.Exit(lockingObject);

        }
        else
            Monitor.Exit(lockingObject);
        Monitor.Enter(lockingObject);
        DataRow[] result = ScheduleConfiguration.Select("ID = "+ID);
        Monitor.Exit(lockingObject);
        //then for each result row, i add this to a static Queue PendingIDs

    }
}