求C#线程澄清

时间:2012-03-18 21:05:58

标签: multithreading visual-studio-2010 c#-4.0

我是线程新手;事实上,我甚至没有尝试多线程处理我正在处理的Windows窗体应用程序,但是我在这个问题上的所有搜索引导我进入多线程主题。在Visual Studio 2010 Express中进行调试时,似乎“跳转”使用我见过其他人用来描述相同问题的术语。当我让它运行时,有时会按预期运行,有时它似乎继续运行,挂起。

在试图磨练我的问题时,我想我需要弄清楚:

如果计时器类在不同的线程上调用方法,并且执行代码中没有明显的不可预测的实例值/状态损坏的危险(没有实例变量的任何条件检查等) ,为什么定时器调用的方法似乎行为不可预测?对我来说,似乎代码应该同步运行,如果一个不同的线程用于进程的一部分,那就这样吧。我看不出哪里有线程损坏的机会。

程序启动时,会提示设置计时器以运行数据下载过程。过程运行后,计时器再次设置为过程结束时的默认时间。始终如一,初始计时器设置工作,并按预期启动,运行数据下载过程...这是数据下载方法,在其中的某个地方出错。最后一行代码是再次设置计时器,但我无法判断它是否在调试时被点击。 (跳来跳去)..

我在下面添加了相关代码......我从一开始就进入了我的代码中的每个程序......它们都显示当前的线程ID 10.这取决于包括计时器启动,并在在下一行执行的断点,即数据下载过程。那时的当前线程:14。我在运行它/尝试调试btw之前构建了解决方案。有什么想法吗?

    public partial class frmTradingAppMain : Form
        {
              private TradingAppDataRunManager drm;

              private void frmTradingAppMain_Shown(object sender, EventArgs e)
              {
                     drm = new TradingAppDataRunManager();
                     drm.StatusChanged += new DataRunManager.DRMStatusChangeHandler(UpdateFormData);
                     drm.InitializeOrScheduleDataRun();
              }

              private void UpdateFormData()
              {
                     this.Invoke(new DataRunManager.DRMStatusChangeHandler(UpdateFormDataImpl));
              }

              private void UpdateFormDataImpl()
              {
                      lblDataDwnLoadManagerStatus.Text = Convert.ToString(drm.Status);

                      if (drm.Status == DataRunManager.DRMStatus.Inactive)
                      {
                            lblNextScheduledDataDownloadDate.Text = "Date not set.";
                            lblNextScheduledDataDownloadTime.Text = "Time not set.";
                      }
                      else
                      {
                            lblNextScheduledDataDownloadDate.Text = drm.DateTimeOfNextScheduledDataRun.ToShortDateString();
                            lblNextScheduledDataDownloadTime.Text = drm.DateTimeOfNextScheduledDataRun.ToShortTimeString();
                       }
               }
        }

    public abstract class DataRunManager
    {
         protected DataRunTimer dataRuntimer;
         public delegate void DRMStatusChangeHandler();
         public event DRMStatusChangeHandler StatusChanged;
         public DRMStatusChangeHandler statusChanged;

         public void InitializeOrScheduleDataRun()
            {
                if (DataRunIsAvailable() && UserWouldLikeToPerformDataRun())
                    RunMainDataProcedure(null);
                else
                    ScheduleDataRun();
            }
         public void RunMainDataProcedure(object state)
            {
                start = DateTime.Now;
                Status = DRMStatus.Running;
                StatusChanged();
                GetDataCollections();
                foreach (DataCollection dcl in dataCollectionList)
                {
                    dcl.RunDataCollection();
                    dcl.WriteCollectionToDatabase();
                }
                PerformDBServerSideProcs();
                stop = DateTime.Now;
                WriteDataRunStartStopTimesToDB(start, stop);
                SetDataRunTimer(DateTimeOfNextAvailableDR());
            }
     public void ScheduleDataRun()
        {
            FrmSetTimer frmSetTimer = new FrmSetTimer(DateTimeOfNextAvailableDataRun);
            DateTime currentScheduledTimeOfNextDataRun = DateTimeOfNextScheduledDataRun;
            DRMStatus currentStatus= Status;

            try
            {
                frmSetTimer.ShowDialog();
                DateTimeOfNextScheduledDataRun = (DateTime)frmSetTimer.Tag;
                SetDataRunTimer(DateTimeOfNextScheduledDataRun);

            }
            catch
            {
                Status = currentStatus;
                DateTimeOfNextScheduledDataRun = currentScheduledTimeOfNextDataRun;
            }
        }
    }

public class DataRunTimer
    {
        System.Threading.Timer timer;

        public DataRunTimer(){}

        public void SetNextDataRunTime(TimerCallback timerCallback,  DateTime timeToSet)
        {
            if (timer == null)
                timer = new System.Threading.Timer(timerCallback);
            TimeSpan delayTime = new TimeSpan(timeToSet.Day - DateTime.Now.Day, timeToSet.Hour - DateTime.Now.Hour, timeToSet.Minute - DateTime.Now.Minute,
                timeToSet.Second - DateTime.Now.Second);

            TimeSpan intervalTime = new TimeSpan(0, 0, 10);
            timer.Change(delayTime, intervalTime);
        }

        public void DataRunTimerCancel()
        {
            if (timer != null)
                timer.Dispose();
        }
    }

0 个答案:

没有答案
相关问题