Почему мое приложение Winforms неожиданно завершает работу, но без ошибок? - PullRequest
1 голос
/ 24 ноября 2011

Я озадачен тем, почему мое приложение Windows2010 для Windows Forms закрывается.

Это происходит в моей основной форме.Эта форма имеет экземпляр класса «менеджер загрузки данных», который работает достаточно хорошо.В коде формы я связываю делегата для обратного вызова для обновления данных в форме, меток, которые отображают состояние DataDownloadManager.

Делегат вызывается всякий раз, когда изменяются переменные состояния в Диспетчере загрузки данных.Это работает, как и ожидалось, например, когда я устанавливаю время загрузки данных (статус диспетчера загрузки данных «Запланировано»).Когда мой таймер выключается и запускает мой метод, переданный делегату, он, кажется, работает большую часть пути, когда я выполняю его (см. Ниже, он правильно устанавливает первые две из трех меток формы в UpdateFormData ()), но когдапопадает в строку для изменения текста «lblDataDwnLoadManagerStatus», ошибки нет, но она быстро завершается.

В какой-то момент у меня не было ошибки, кроме всплывающего сообщения в режиме отладки, в котором упоминалось исключение между потоками, которое я не могу воссоздать.Надеюсь, это понятно.

Любая помощь будет отличной.Код приведен ниже, и, кстати, TradingAppDataRunManager получает все функции из DataRunManager, включенные ниже.

public partial class frmTradingAppMain : Form
{

    private TradingAppDataRunManager drm;

    public frmTradingAppMain()
    {
        InitializeComponent();
    }

    private void frmTradingAppMain_Load(object sender, EventArgs e){}

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

    private void UpdateFormData()
    {
        MessageBox.Show("This is a test");

        lblNextScheduledDataDownloadDate.Text = drm.DateTimeOfNextScheduledDataRun.ToShortDateString();
        lblNextScheduledDataDownloadTime.Text = drm.DateTimeOfNextScheduledDataRun.ToShortTimeString();
        lblDataDwnLoadManagerStatus.Text = Convert.ToString(drm.Status);
    }

    private void btnSetChangeOrCancelScheduledDataRunTime_Click(object sender, EventArgs e)
    {
        drm.InitializeOrScheduleDataRun();
    }

    private void btnExit_Click(object sender, EventArgs e)
    {
        Close();
    }
}

public abstract class DataRunManager
//The base class for the upper- level, overall management for an app's data downloading and processing.
{
    private List<DataCollection> dataCollectionList = new List<DataCollection>();
    private List<PerformanceTrackerPoint> performanceTrackerPoint;
    private List<Error> errorCollection;
    protected DataRunTimer timer;
    protected SqlConnection sqlConnection;
    public enum DRMStatus { Running, Scheduled, Inactive }
    public DRMStatus Status { get; set; }
    public DateTime DateTimeOfNextAvailableDataRun { get; set; }        //This is the time that is checked from the database.
    public DateTime DateTimeOfNextScheduledDataRun { get; set; }        //This is the time that gets set for the run.
    public delegate void StatusChangeHandler();
    public event StatusChangeHandler StatusChanged;
    protected abstract String SQLSelectStringForDateOfLastDataRun();
    protected abstract void SetDBConnection();
    protected abstract List<DataCollection> GetDataCollectionsFromSubclass();

    public void InitializeOrScheduleDataRun()
    {
        DateTimeOfNextAvailableDataRun = DateTimeOfNextDataRun();

        if (DataRunIsOverdue())
        {
            if (UserWouldLikeToPerformDataRun())
            {
                Status = DRMStatus.Running;
                RunMainDataProcedure(null);
            }
            else
            {
                ScheduleDataRun();
                Status = DRMStatus.Scheduled;
            }
        }
        StatusChanged();
    }

Ответы [ 2 ]

4 голосов
/ 24 ноября 2011

Вы никогда не должны обращаться к элементу управления WinForms из другого потока, в котором он был создан.

Если ваш класс DataRunManager использует отдельный поток для некоторой обработки, а затем этот поток запускает событие StatusChanged, тогда обработчик события обрабатывается в другом потоке, отличном от того, который создал ярлыки WinForms, которые вы обновляете.Поэтому измените ваш обработчик событий следующим образом ...

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

private void UpdateFormDataImpl() 
{ 
    lblDataDwnLoadManagerStatus.Text = Convert.ToString(drm.Status); 
} 
2 голосов
/ 24 ноября 2011

Вам, вероятно, нужно обработать событие AppDomain.UnhandledException

  AppDomain currentDomain = AppDomain.CurrentDomain;
  currentDomain.UnhandledException += new UnhandledExceptionEventHandler(MyHandler);

С ведением журнала или чем-то еще здесь ...

   static void MyHandler(object sender, UnhandledExceptionEventArgs args) {
      Exception e = (Exception) args.ExceptionObject;
      Console.WriteLine("MyHandler caught : " + e.Message);
   }

Это должно перехватывать любые исключения, которые запутываютпуть к вершине и прекратить ваше приложение.

Поймайте полную страницу Microsoft здесь ... http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx

...