C# winForm 窗体关闭前的线程处理

zhaoxiuyong 2016-05-11 05:08:57
最近给客户做指挥调度系统,遇到个棘手的问题,请万能的坛友指条明路。问题是这样的,怕我语言表达能力有限,先上图



private void DrawCarToMap()
{
while(run)
{
取队列数据;
brower.Document.InvokeScript(gpsData)//执行浏览器的脚本向地图画轨迹
Thread.Sleep(500);
}
}

private void GPS_Event(GPSEventArgs gpsData)
{
压数据到队列
}

private void window_closeing()
{
run = false;
GPS_Event解绑;
try{
DrawMap.Abort();
}catch{}
}


问题就出在窗口关闭时经常引起整个程序崩溃,怀疑是正好关闭时浏览器正在执行脚本,或是正好在执行这一步brower.Document.InvokeScript(gpsData)对已经销毁的资源访问引起程序崩溃。由于本系统要7*24小时不间断运行,并有呼叫中心功能。请大神支招,万分感谢。这问题困扰很久了
...全文
1074 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
秋的红果实 2016-06-13
  • 打赏
  • 举报
回复
while(run) { 取队列数据; brower.Document.InvokeScript(gpsData)//执行浏览器的脚本向地图画轨迹 Thread.Sleep(500); } 画轨迹,单独开一个线程,试一试
失落的神庙 2016-06-13
  • 打赏
  • 举报
回复
别用webbrowser了。 用第三方的如。 chrome内核。
zhaoxiuyong 2016-06-12
  • 打赏
  • 举报
回复
csdn人气低迷
zhaoxiuyong 2016-06-06
  • 打赏
  • 举报
回复
引用 19 楼 jiangsheng 的回复:
禁用CheckForIllegalCrossThreadCalls只是把线程里访问Windows Forms控件这个bug的检查禁用而已,不是说这个bug就不存在了。
你的脚本执行代码应该在UI线程。从Winforms到ActiveX到脚本引擎,没有一层是线程安全的。

有什么好的建议吗?
zhaoxiuyong 2016-06-03
  • 打赏
  • 举报
回复
还是没找到问题所在,调试模式下都跟踪不到BUG的位置,程序直接就挂掉了。会不会我把问题定位搞错错了,可能不是线程引起的,会不会是那个厂家提供的OCX控件问题,所以就跟踪不到bug位置,日志也记录不到。
蒋晟 2016-06-03
  • 打赏
  • 举报
回复
禁用CheckForIllegalCrossThreadCalls只是把线程里访问Windows Forms控件这个bug的检查禁用而已,不是说这个bug就不存在了。 你的脚本执行代码应该在UI线程。从Winforms到ActiveX到脚本引擎,没有一层是线程安全的。
小枪 2016-05-31
  • 打赏
  • 举报
回复
要么加循环或者计时器 判断线程状态再进行线程abort
zhaoxiuyong 2016-05-31
  • 打赏
  • 举报
回复
引用 11 楼 sp1234 的回复:
什么叫做“日志记不到”?你是怎样记录日志的?

program.cs里

[STAThread]
static void Main(string[] args)
{
Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
}

static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs ex)
{
try
{
Exception e = (Exception)ex.ExceptionObject;
YGApp.Base.Log.IYGAppLog log = YGApp.Base.Log.YGAppLogFactory.GetLog(YGApp.Base.Const.LogTypeEnum.UI);
log.Error("全局未处理异常CurrentDomain_UnhandledException:" + e.Message + "\r\n" + e.Source + "\r\n" + Remis.Common.CommonPublic.GetEntitysString(e.Data), e);
}
catch
{
System.Diagnostics.EventLog.WriteEntry("RemisSetup", ex.ToString(), System.Diagnostics.EventLogEntryType.Error);
}
finally
{
System.Diagnostics.EventLog.WriteEntry("RemisSetup", ex.ToString(), System.Diagnostics.EventLogEntryType.Error);
}
}

/// <summary>
/// 全局线程异常处理事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
try
{
YGApp.Base.Log.IYGAppLog log = YGApp.Base.Log.YGAppLogFactory.GetLog(YGApp.Base.Const.LogTypeEnum.UI);
log.Error("全局未处理异常Application_ThreadException:" + e.Exception.Message + "\r\n" + e.Exception.Source + "\r\n" + Remis.Common.CommonPublic.GetEntitysString(e.Exception.Data), e.Exception);
}
catch
{
System.Diagnostics.EventLog.WriteEntry("RemisSetup", e.ToString(), System.Diagnostics.EventLogEntryType.Error);
}
finally
{
System.Diagnostics.EventLog.WriteEntry("RemisSetup", e.ToString(), System.Diagnostics.EventLogEntryType.Error);
}
}

john_QQ:2335298917 2016-05-31
  • 打赏
  • 举报
回复
你可以在程序退出时,等待正在运行的线程退出,方法甚至可以是简单的sleep,只要你sleep的时间超过等待线程退出的时间即可,界面上可以进行提示,正在等待线程退出,这样虽说退出的时候程序显得慢一点,但是不会崩溃。
zhaoxiuyong 2016-05-31
  • 打赏
  • 举报
回复
引用 12 楼 xdashewan 的回复:
[quote=引用 10 楼 zhaoxiuyong 的回复:]
做了这一步判断只能减少出现的次数,也有极少情况出现闪退。刚才执行了判断后对象销毁了

你如果在线程里执行while,可以在关闭时候用thread.Join方法等待线程结束,也就是run = false;后循环退出后再执行closing的后续代码[/quote]
谢谢,我试下。
zhaoxiuyong 2016-05-31
  • 打赏
  • 举报
回复
引用 11 楼 sp1234 的回复:
什么叫做“日志记不到”?你是怎样记录日志的?
program.cs里 <code> [STAThread] static void Main(string[] args) { Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException); Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); } static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs ex) { try { Exception e = (Exception)ex.ExceptionObject; YGApp.Base.Log.IYGAppLog log = YGApp.Base.Log.YGAppLogFactory.GetLog(YGApp.Base.Const.LogTypeEnum.UI); log.Error("全局未处理异常CurrentDomain_UnhandledException:" + e.Message + "\r\n" + e.Source + "\r\n" + Remis.Common.CommonPublic.GetEntitysString(e.Data), e); } catch { System.Diagnostics.EventLog.WriteEntry("RemisSetup", ex.ToString(), System.Diagnostics.EventLogEntryType.Error); } finally { System.Diagnostics.EventLog.WriteEntry("RemisSetup", ex.ToString(), System.Diagnostics.EventLogEntryType.Error); } } /// <summary> /// 全局线程异常处理事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e) { try { YGApp.Base.Log.IYGAppLog log = YGApp.Base.Log.YGAppLogFactory.GetLog(YGApp.Base.Const.LogTypeEnum.UI); log.Error("全局未处理异常Application_ThreadException:" + e.Exception.Message + "\r\n" + e.Exception.Source + "\r\n" + Remis.Common.CommonPublic.GetEntitysString(e.Exception.Data), e.Exception); } catch { System.Diagnostics.EventLog.WriteEntry("RemisSetup", e.ToString(), System.Diagnostics.EventLogEntryType.Error); } finally { System.Diagnostics.EventLog.WriteEntry("RemisSetup", e.ToString(), System.Diagnostics.EventLogEntryType.Error); } } </code>
xdashewan 2016-05-30
  • 打赏
  • 举报
回复
引用 10 楼 zhaoxiuyong 的回复:
做了这一步判断只能减少出现的次数,也有极少情况出现闪退。刚才执行了判断后对象销毁了
你如果在线程里执行while,可以在关闭时候用thread.Join方法等待线程结束,也就是run = false;后循环退出后再执行closing的后续代码
  • 打赏
  • 举报
回复
什么叫做“日志记不到”?你是怎样记录日志的?
zhaoxiuyong 2016-05-28
  • 打赏
  • 举报
回复
引用 9 楼 xdashewan 的回复:
判断browser != null && !browser.IsDisposed再执行后面

做了这一步判断只能减少出现的次数,也有极少情况出现闪退。刚才执行了判断后对象销毁了
xdashewan 2016-05-26
  • 打赏
  • 举报
回复
判断browser != null && !browser.IsDisposed再执行后面
zhaoxiuyong 2016-05-26
  • 打赏
  • 举报
回复
坛子越来越冷清了
zhaoxiuyong 2016-05-24
  • 打赏
  • 举报
回复
引用 5 楼 drifter2002 的回复:
退出窗口之前,等待其他工作线程退出后再退出主线程。
怎么个等待法?使用这个System.Threading.AutoResetEvent同步?
zhaoxiuyong 2016-05-24
  • 打赏
  • 举报
回复
引用 4 楼 ta_wuhen 的回复:
如果有线程,把线程设置为后台线程。具体错误查不到?

查不到是哪里的错误,日志记不到,用原代码调试状态都跟踪不到错误直接闪退了。
drifter2002 2016-05-23
  • 打赏
  • 举报
回复
退出窗口之前,等待其他工作线程退出后再退出主线程。
我现在在路上 2016-05-18
  • 打赏
  • 举报
回复
如果有线程,把线程设置为后台线程。具体错误查不到?
加载更多回复(3)

110,536

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧