C#:当我尝试移动窗口、单击外部或最小化时,窗口挂起

Posted

技术标签:

【中文标题】C#:当我尝试移动窗口、单击外部或最小化时,窗口挂起【英文标题】:C#: Window hangs when I try to move it, click outside or minimize 【发布时间】:2018-07-02 01:11:06 【问题描述】:

这是我正在尝试运行的应用程序的图片:

当我尝试在外部单击、移动或最小化它时,窗口会挂起:

我的代码:

        public void Process()
    
        //            using (HalconDotNet.HWindowControl HWinCtrl = new HalconDotNet.HWindowControl())
        //            
        using (PitFinderEngine VisionEngine = new PitFinderEngine())
        

            foreach (string jpegfile in JpegFiles)
            
                try
                
                    string[] parts1 = jpegfile.Split('\\');
                    string[] parts2 = parts1[parts1.Length - 1].Split('.')[0].Split('_');
                    string row = parts2[parts2.Length - 2].Split('R')[1];
                    string col = parts2[parts2.Length - 1].Split('C')[1];
                    Results.Add(row + " " + col, VisionEngine.action(jpegfile, "Production"));
                    //FormControls.ProgressBar_DoStep();
                
                catch (Exception e)
                

                
            

        
    

“进程”以这种方式调用:

    public static Thread StartTheThread(string LN, string TN)
    
        var t = new Thread(() => RealStart(LN, TN));
        t.Start();
        return t;
    

    private static void RealStart(string ln, string tn) 
            Lots[ln].Tiles[tn].Process();

    


    public static void DoWork()
    
        string[] Directories = Directory.GetDirectories(LotPictureFolder);
        List<Thread> ThreadList = new List<Thread>();
        foreach (string lot in Directories)
        
            string[] parts = lot.Split('\\');
            string LotName = parts[parts.Length - 1];
            foreach (string tile in Lots[LotName].Tiles.Keys)
            
                if (!Lots[LotName].Tiles[tile].VicFileFound)
                
                    ThreadList.Add(StartTheThread(LotName, tile));
                

            
        

        bool AllDone = false;
        while (!AllDone)
        
            AllDone = true;
            foreach (Thread th in ThreadList)
            
                if (th.IsAlive)
                
                    AllDone = false;
                
            
        
    

好像

VisionEngine.action(jpegfile, "Production")

运行需要 10ms - 20ms 并负责挂起窗口,如果我要移动窗口;意思是,如果我要评论它,问题就不会存在,是否可以隔离此代码,我尝试使用线程,但问题仍然存在,我无法使用任务,因为平台是 .Net3.5。

【问题讨论】:

【参考方案1】:

问题在于,当您为应用程序运行较长的任务时,它会阻塞UI,直到订单完成。那是因为您的任务阻止了此订单的MainThread,因此UI 无法响应,因为它也在MainThread 中运行。因为UI 不响应 Windows,所以它告诉您:嘿,注意这个窗口当前不响应任何用户操作。

即使您的应用程序在后台执行了很多操作(您指定应用程序执行的操作),但这对于用户和 Windows 来说并不重要。问题是,一旦您在应用程序上单击更多,被阻止的UI,Windows 仍然会注意到并建议您关闭窗口,因为看起来应用程序被卡住了。

只需在长时间运行的任务中使用Application.DoEvents()。其行为如下:

调用此方法会导致当前线程暂停,同时处理所有等待窗口消息。

因此它会暂停您当前长时间运行的任务,以处理来自例如用户输入,因此最大化,移动,...窗口。之后,它将继续处理您的长期订单。

Application.DoEvents();

这意味着如果例如您的方法需要 10 秒才能完成,调用 Application.DoEvents() 一次会使您的应用程序只处理一次用户操作,这似乎不是您想要的行为。所以你必须多次调用它。请注意,这会使您的运行方法显着变慢。

【讨论】:

仍然没有帮助:( 是的,很抱歉没有发表评论【参考方案2】:

此时您似乎不再使用 ThreadList。您的整个过程方法应该启动一个新线程。然后确保您修改 ProgressBar 的事件是进度。一旦所有代码在单独的线程上运行,您的 UI 就不应再因此而冻结。

【讨论】:

以上是关于C#:当我尝试移动窗口、单击外部或最小化时,窗口挂起的主要内容,如果未能解决你的问题,请参考以下文章

隐藏标准标题栏时如何移动窗口

WinAPI - 钩住鼠标

尝试通过单击打开它的 div 中断按钮外部来关闭弹出窗口

用户单击即可打开多个指向外部站点的选项卡/窗口

在 ExtJS 4.1 中单击外部窗口时如何关闭窗口?

在窗口范围内限制/移动上下文菜单(右键单击)