• 全部
  • C#综合技术
  • C#互联网桌面应用
  • AppLauncher
  • WinForm&WPF
  • C#开发新技术
  • 问答

帮忙看看这个程序,一打开就死机。哪里错了?

myvvc 2015-10-27 08:08:19
我的一个实时监控程序一打开就死机。内存不够用。
Timer里不能加循环吗??

知道的在这个链接里也问答一下,我把这个帖子结了。
http://bbs.csdn.net/topics/391848699


private void timer1_Tick(object sender, EventArgs e)
{
for (int i = 210; i <= 850; i += 1)
{
for (int j = 320; j <= 500; j += 1)
{
Point ap = new Point(i, j);
IntPtr ahdc = GetDC(new IntPtr(0));
int ac = GetPixel(ahdc, ap);
if (ac == 255)
{
label1.text = "Error"
break;
}
}
}
}
...全文
159 点赞 收藏 8
写回复
8 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
qbilbo 2015-10-28
颜色的比较写随手了,把:if (c == Color.White)改成:if(c.ToArgb() == Color.White.ToArgb())
回复
qbilbo 2015-10-28
            DateTime b = DateTime.Now;

            Rectangle rect = new Rectangle();
            rect.X = 210;
            rect.Y = 320;
            rect.Width = 850 - 210;
            rect.Height = 500 - 320;

            using (Bitmap bmp = new Bitmap(rect.Width, rect.Height))
            {
                using (Graphics g = Graphics.FromImage(bmp))
                {
                    g.CopyFromScreen(rect.X, rect.Y, 0, 0, new Size(rect.Width, rect.Height));
                }

                for (int i = 0; i < rect.Width; i++)
                {
                    for (int j = 0; j < rect.Height; j++)
                    {
                        Color c = bmp.GetPixel(i, j);

                        if (c == Color.White)
                        {
                            throw new Exception("颜色错误。");
                        }
                    }
                }
            }
            double d = (DateTime.Now - b).TotalMilliseconds;

            MessageBox.Show(string.Format("检测结束,共用时:{0}毫秒。", d));
不用调用Win32 API的,.Net都封装好了。
回复
mingcsharp 2015-10-28
引用 5 楼 unearth 的回复:
(850-210) * (500 -320) =115200,确定 这些事情,能在6秒内完成 ,而且,在这些循环内,WM_PAINT消息是无法被界面程序处理的。 你可以用线程,或让权(System.Windows.Forms.Application.DoEvent())函数来处理Windows 发送界面的消息。
最好多线程
回复
孤独de猫 2015-10-27
(850-210) * (500 -320) =115200,确定 这些事情,能在6秒内完成 ,而且,在这些循环内,WM_PAINT消息是无法被界面程序处理的。 你可以用线程,或让权(System.Windows.Forms.Application.DoEvent())函数来处理Windows 发送界面的消息。
回复
classbob 2015-10-27
1. 设置一个标志,避免前一Tick尚未完成时第二个又进来 2. 把GetDC提到循环外面去 3. GetDC要与ReleaseDC配对 4. break只跳出了一层循环,外层循环还会继续

private volatile bool _flag = false;

private void timer1_Tick(object sender, EventArgs e)
        {
if(_flag) { return; }
_flag = true;
bool bBreak = false;

IntPtr ahdc = GetDC(new IntPtr(0));

            for (int i = 210; i <= 850; i += 1)
            {
if(bBreak) break;
                for (int j = 320; j <= 500; j += 1)
                {
if(bBreak) break;
                    Point ap = new Point(i, j);                    
                    int ac = GetPixel(ahdc, ap);
                    if (ac == 255)
                    {
                        label1.text = "Error"
bBreak = true;
                    }
                }
            }

ReleaseDC(ahdc);
_flag = false;
        }
回复
Poopaye 2015-10-27
你原来那贴不是有人说了,GetDC的结果要释放(ReleaseDC) 你不释放也可以,把代码移到最外面 IntPtr ahdc; private void timer1_Tick(object sender, EventArgs e) { if(ahdc == IntPtr.Zero) ahdc = GetDC(new IntPtr(0)); for(.......... }
回复
myvvc 2015-10-27
引用 1 楼 tanaichuan 的回复:
timer1_Tick 时间设置太短了吧?可能里面的循环还没完 就又循环了。。这样造成了无限循环。加个条件判断下。。。比如设置个全局变量 设置在循环外面、、、然后 判断是否循环完成。
现在interval=5000,我试着改成了60000,程序未响应。 CPU占用50%,内存10M左右,是循环太大了吗?我需要确认这个区域的所有点,有没有优化的算法?头疼ing......
回复
tanaichuan 2015-10-27
timer1_Tick 时间设置太短了吧?可能里面的循环还没完 就又循环了。。这样造成了无限循环。加个条件判断下。。。比如设置个全局变量 设置在循环外面、、、然后 判断是否循环完成。
回复
发帖
C#
创建于2007-09-28

10.5w+

社区成员

.NET技术 C#
申请成为版主
帖子事件
创建了帖子
2015-10-27 08:08
社区公告

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