2011-11-24 61 views
1

我很困惑爲什麼我的VS2010 Windows窗體應用程序正在關閉。爲什麼我的Winforms應用程序意外退出,但沒有錯誤?

它發生在我的主要形式。這種形式有一個「數據下載管理器」類的實例運行良好。在表單的代碼中,我將綁定到一個回調委託來更新表單上的數據,標籤顯示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(); 
    } 
+0

要麼檢查輸出窗口或使所有異常的報告 - Visual Studio將不會通知您在默認情況下許多例外。轉到Debug - > Exceptions ...然後勾選Thrown for Common Language Runtime Exceptions,然後單擊OK。再次運行你的代碼,看看它現在是否拋出異常。 –

回答

4

您不應該從創建它的其他線程訪問WinForms控件。

如果您的DataRunManager類正在使用單獨的線程進行某些處理,然後該線程正在觸發StatusChanged事件,則事件處理程序正在與創建正在更新的WinForms標籤不同的線程上處理。因此,改變你的事件處理程序大致如下......

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

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

菲爾,謝謝......我是全新的代表,線程......我不知道不同的線程以這種方式「脫離」而沒有明確地這樣做。這是代表這種類型的問題,只有在Windows窗體環境中? – StatsViaCsh

+0

我只是猜測你正在使用額外的線程,因爲你收到的異常表明一個跨線程問題,並且知道你不能從不同線程訪問WinForm控件。檢查你的RunMainDataProcedure和ScheduleDataRun,看他們是否爲他們的操作創建/使用線程。 –

+0

這是我的下一步。我的代碼沒有創建一個單獨的線程,除非它發生在某個地方,或者是隱含的,我不知道它。我很少使用代表期間,所以我有更多的閱讀需要做。 – StatsViaCsh

2

你可能需要處理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

+0

順便說一下,這應該是在打開任何表單之前在Program.Main方法。 – JTew

+0

嘿謝謝,現在正在實施... – StatsViaCsh

相關問題