为什么我的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();
}
答案 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