为什么我的Winforms应用程序意外退出,但没有错误?

时间:2011-11-24 01:10:06

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

为什么我的VS2010 Windows窗体应用程序正在关闭,我感到很困惑。

它以我的主要形式发生。这个表单有一个运行良好的“数据下载管理器”类的实例。在表单的代码中,我绑定了一个委托,用于回调更新表单上的数据,标签显示DataDownloadManager的状态。

每当数据下载管理器中的状态变量发生更改时,都会调用委托。这可以按预期工作,例如当我设置数据下载时间时(数据下载管理器的状态为“已安排”)。当我的计时器关闭并运行我的方法传递给委托时,它似乎在我执行它的过程中大部分工作(见下文,它正确设置UpdateFormData()中三个表单标签的前两个),但是当它到达行更改“lblDataDwnLoadManagerStatus”的文本,没有错误,但它会立即退出。

在某一点上,我没有出现错误,而是在调试模式下的一个flyout消息提到了一个跨线程异常,我无法重新创建。我希望这很清楚。

任何帮助都会很棒。代码如下,以及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 个答案:

答案 0 :(得分:4)

您永远不应该从创建它的其他线程访问WinForms控件。

如果您的DataRunManager类使用单独的线程进行某些处理,然后该线程触发StatusChanged事件,则事件处理程序将在与创建您正在更新的WinForms标签的线程不同的线程上处理。因此,请沿着以下行更改事件处理程序...

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

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

答案 1 :(得分:2)

您可能需要处理AppDomain.UnhandledException事件

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

使用Logging或此处的任何内容......

   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