C#写的WinForm程序运行较长一段时间就会崩溃或者自动退出。

坚持着的沉默者 2018-09-14 10:16:04
刚开始接触C#,最近在用C#写一个WIFI自动连接的小程序,目标是该程序能够持续检测并且运行,如果检测到想要连接的指定WiFi断开,会自动连接。该程序通过扫描附近的wifi信息,然后存在list中,然后检测指定的wifi信号是否低于设置的信号或者已经断开连接,如果是,则自动重连。指定的wifi名和ssid以及wifi连接的命令存储在connectWifi.bat文件中:

wifi连接的代码如下:

public void ConnectToSSID()
{
string str1 = System.IO.Directory.GetCurrentDirectory();
Process proc = null;
try
{
LogHelper.WriteLog(0, "正在执行网络重启");
string targetDir = string.Format(@".\config");//this is where mybatch.bat lies
proc = new Process();
proc.StartInfo.WorkingDirectory = targetDir;
proc.StartInfo.FileName = "connectWifi.bat";
proc.StartInfo.Arguments = string.Format("10");//this is argument
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
proc.Start();
proc.WaitForExit();
LogHelper.WriteLog(0, "网络重启完成");
}
catch (Exception ex)
{
//Console.WriteLine("Exception Occurred :{0},{1}", ex.Message, ex.StackTrace.ToString());
throw;
}
}

该程序是一个多线程的程序,除了连接WiFi以外,会生成一个窗体,窗体上会显示信号的强度,以及基本的日志文本,如下:
进度条和信号强度的标签都是委托,代码如下:

日志的显示我把它写为后台线程,显示日志的代码如下:

private void LogerWatch()
{
while(flag_Form)
{
if (!this.IsHandleCreated || this.IsDisposed)
{
continue;
}
else
{
flag_Form = false;
}
}
while (logWatching && !flag_Form)
{
LoggingEvent[] events = appender.GetEvents();
this.wifi_Quality_ProgressBar.BeginInvoke(uPB_CallBack, (int)wifiso.CurrentWifiQuality);
this.wifi_Quality_Label.BeginInvoke(uL_CallBack, ("信号强度:"+(int)wifiso.CurrentWifiQuality).ToString());
if (events != null && events.Length > 0)
{

// if there are events, we clear them from the logger,

// since we're done with them
appender.Clear();
foreach (LoggingEvent ev in events)
{
//string line = ev.LoggerName + ": " + ev.RenderedMessage + "\r\n";
string line = ev.RenderedMessage + "\r\n";
AppendLog(line);



}

}



Thread.Sleep(1000);
}
}

private void AppendLog(string line)
{
if (textBox1.InvokeRequired)
{
BeginInvoke(new Action<string>(DoAppendLog), line);
}
else
{
DoAppendLog(line);
}
}

private void DoAppendLog(string line)
{
if (textBox1.Lines.Length > 99)
{
var builder = new StringBuilder(textBox1.Text);

// strip out a nice chunk from the beginning
builder.Remove(0, textBox1.Text.IndexOf('\r', 500) + 2);
builder.Append(line);
textBox1.Clear();

// using AppendText since that makes sure the TextBox stays

// scrolled at the bottom
textBox1.AppendText(builder.ToString());
}
else
{
textBox1.AppendText(line);
}
}

这个程序在四台机子上持续运行了四天,然后在一台机子上出现了一次崩溃的现象,重新启动之后两天,在各个机子上陆续出现自动退出的情况,并且都未报错。还请大佬指点,很急!!!!!
因为我自己认为出现问题的原因可能是因为多线程的缘故,也就是连接和日志显示部分,并且还有一些原因我不能展示太多的代码,所以我只展示了这两部分的代码,如有需要并且可以的话,我可以在评论区将各位大佬所需代码展示出来。希望大佬帮忙。

...全文
5667 29 打赏 收藏 转发到动态 举报
写回复
用AI写文章
29 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
引用 28 楼 daixf_csdn 的回复:
1、显然是内存溢出了,有资源没释放
2、问题很可能不是出在你贴的代码上,比如输出日志。你可以考虑把输出日志代码屏蔽掉,所有不关键的代码都屏蔽,在运行几天试试。
3、运行期间观察:任务管理器中,进程的内存使用有没有在一直上涨
4、代码中的这句throw,也可能会导致系统退出(但一旦发生一次异常时)。你先把throw屏蔽掉。
catch (Exception ex)
{
throw;
}

输出日志这个功能不能去掉。。。。因为需要,,,,
  • 打赏
  • 举报
回复
引用 22 楼 xuzuning 的回复:
System.OutOfMemoryException
内存溢出,也就是说:已无足够的内存空间可供使用了
这就是资源耗尽

在你贴出的代码中,只看到创建对象,而无销毁对象的代码

LoggingEvent[] events = appender.GetEvents();
是这个导致内存溢出的吗?
圣殿骑士18 2018-09-17
  • 打赏
  • 举报
回复
1、显然是内存溢出了,有资源没释放
2、问题很可能不是出在你贴的代码上,比如输出日志。你可以考虑把输出日志代码屏蔽掉,所有不关键的代码都屏蔽,在运行几天试试。
3、运行期间观察:任务管理器中,进程的内存使用有没有在一直上涨
4、代码中的这句throw,也可能会导致系统退出(但一旦发生一次异常时)。你先把throw屏蔽掉。
catch (Exception ex)
{
throw;
}
yanghao1 2018-09-17
  • 打赏
  • 举报
回复
一般是Windows问题,内部可能有不良软件在后台运行占据了大量资源,就会出现这种情况。
xuzuning 2018-09-16
  • 打赏
  • 举报
回复
不外是资源耗尽或有致命错误
圣殿骑士18 2018-09-16
  • 打赏
  • 举报
回复
引用 10 楼 daixf_csdn 的回复:
[quote=引用 6 楼 qq_41592828 的回复:]
[quote=引用 5 楼 jianmin91 的回复:]
把异常打印出来看看

他没报异常,直接退出。[/quote]
windows日志里可以看到异常[/quote]
windows日志看了没??
  • 打赏
  • 举报
回复
引用 26 楼 Ruoch 的回复:
你缺少线程 把线程模块加进去!!!

缺少什么线程。。。。缺少线程程序能运行四天吗、、、、
  • 打赏
  • 举报
回复
引用 14 楼 mirror030 的回复:
初略看一下,应该是while里的代码死循环了

在关闭窗体之前,就是要让他一直循环,为了将日志打出来,窗体的关闭事件中设置了,当关闭窗体的时候,标志变量会变为false,循环退出
Ruoch 2018-09-16
  • 打赏
  • 举报
回复
你缺少线程 把线程模块加进去!!!
  • 打赏
  • 举报
回复
引用 24 楼 vokxchh 的回复:
多久执行一次。
会不会 proc.WaitForExit();
卡死了。

目的是长时间运行。。。。
vokxchh 2018-09-16
  • 打赏
  • 举报
回复
多久执行一次。
会不会 proc.WaitForExit();
卡死了。
mirrorspace 2018-09-16
  • 打赏
  • 举报
回复
初略看一下,应该是while里的代码死循环了
  • 打赏
  • 举报
回复
引用 22 楼 xuzuning 的回复:
System.OutOfMemoryException
内存溢出,也就是说:已无足够的内存空间可供使用了
这就是资源耗尽

在你贴出的代码中,只看到创建对象,而无销毁对象的代码

我刚开始接触C#,好多都是别人写好的,我在基础上进行修改,所以还请大佬详细说明一下在哪里修改,销毁哪部分对象,抱拳了!
xuzuning 2018-09-16
  • 打赏
  • 举报
回复
System.OutOfMemoryException
内存溢出,也就是说:已无足够的内存空间可供使用了
这就是资源耗尽

在你贴出的代码中,只看到创建对象,而无销毁对象的代码
  • 打赏
  • 举报
回复
应用程序: wifiConnect.exe
Framework 版本: v4.0.30319
说明: 由于未经处理的异常,进程终止。
异常信息: System.OutOfMemoryException
在 System.Environment.GetResourceFromDefault(System.String)
在 System.Environment.GetResourceString(System.String, System.Object[])
在 System.Exception.get_Message()
在 System.Windows.Forms.ThreadExceptionDialog..ctor(System.Exception)
在 System.Windows.Forms.Application+ThreadContext.OnThreadException(System.Exception)
在 System.Windows.Forms.Control.WndProcException(System.Exception)
在 System.Windows.Forms.Control+ControlNativeWindow.OnThreadException(System.Exception)
在 System.Windows.Forms.NativeWindow.Callback(IntPtr, Int32, IntPtr, IntPtr)
在 System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG ByRef)
在 System.Windows.Forms.Application+ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr, Int32, Int32)
在 System.Windows.Forms.Application+ThreadContext.RunMessageLoopInner(Int32, System.Windows.Forms.ApplicationContext)
在 System.Windows.Forms.Application+ThreadContext.RunMessageLoop(Int32, System.Windows.Forms.ApplicationContext)
在 System.Windows.Forms.Application.Run(System.Windows.Forms.Form)
在 AutoConnectWifi.Program.Main()

错误应用程序名称: wifiConnect.exe,版本: 1.0.0.0,时间戳: 0x5b8f6acf
错误模块名称: KERNELBASE.dll,版本: 6.1.7601.23889,时间戳: 0x598d4d26
异常代码: 0xe0434352
错误偏移量: 0x0000c54f
错误进程 ID: 0x1dd4
错误应用程序启动时间: 0x01d44bd38ffb907e
错误应用程序路径: C:\Users\dell\Desktop\Release\wifiConnect.exe
错误模块路径: C:\Windows\syswow64\KERNELBASE.dll
报告 ID: cf449c95-b83b-11e8-ad96-005056c00008



大佬们,上面就是windows日志里显示的错误信息,求解。
  • 打赏
  • 举报
回复
引用 17 楼 xuzuning 的回复:
不外是资源耗尽或有致命错误

我感觉也可能是。。。但是windows的日志看不懂。。。
  • 打赏
  • 举报
回复
引用 16 楼 daixf_csdn 的回复:
[quote=引用 10 楼 daixf_csdn 的回复:]
[quote=引用 6 楼 qq_41592828 的回复:]
[quote=引用 5 楼 jianmin91 的回复:]
把异常打印出来看看

他没报异常,直接退出。[/quote]
windows日志里可以看到异常[/quote]
windows日志看了没??[/quote]
看到了,这个问题又复现了,但是看不懂
  • 打赏
  • 举报
回复
软件不太可能简单地永远运行。就算是一些自己执行几年免维护的软件,可能它内部不断地重新连接、不断地重新设置,甚至使用另外一个守护进程不断地重新拉起业务进程。

那么改进发布出去的 Release 程序的质量的重点,还是回到本源,就是要有恰当的(而不是含糊其辞的)日志。起码能让你知道具体是哪一行代码崩溃的、崩溃之前当时的诊断变量值是什么。
  • 打赏
  • 举报
回复
引用 4 楼 qq_41592828 的回复:
[quote=引用 3 楼 a755362405 的回复:]
看下系统的日志是否记录了错误,没有的话可以考虑在程序入口点增加全局异常捕获。

没有报错,已经加上全局异常捕获。[/quote]

首先,所谓“没有报错”往往是开发中加了错误的 try...catch。假设开发中习惯于隐瞒错误的编程思路,那么真正需要跟踪错误时你就反而看不到报错信息了。所以首先要检查 try....catch,禁止滥用 try....catch。然后,仅仅在 Release 版本才启用必要的 try...catch 和异常捕获。

其次,你想想看,即使“没有报错”你也应该可以通过至少2条日志来逐步逼近程序崩溃的具体语句。只要是错误可以稍微稳定地重现在相同语句上,怎么可能找不到错误语句呢?
  • 打赏
  • 举报
回复
程序的 Debug 和 Release 版本的代码是不一样的。

对于 Release版本,在程序异常退出之前,我们需要捕获 AppDomain.CurrentDomain.UnhandledException 事件并且打印 UnhandledExceptionEventArgs 的 ExceptionObject参数,以及 AppDomain.CurrentDomain 的一些属性到日志里。同时在一些重要过程中,也需要打印 Catch 到的 Exception 信息和当时运行信息到日志中。

所以要诊断 Release 程序的 bug,我们首先要看日志。假设你说不出来程序运行到哪一条、哪一行代码而退出了,那么这个时候就没有把工作做到位。
加载更多回复(9)

111,075

社区成员

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

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

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