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

标签 c# .net windows multithreading

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

enter image description here

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

enter image description here

我的代码:

        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。

最佳答案

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

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

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

Calling this method causes the current thread to be suspended while all waiting window messages are processed.

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

Application.DoEvents();

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

关于C#:当我尝试移动窗口、单击外部或最小化窗口时,窗口会挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48397933/

相关文章:

objective-c - 如何编译在 Windows 上使用 NSApplication 的 GNUstep 应用程序?

c# - 需要帮助确定小型 C# 数字到百分位数转换程序中的错误来源

C# - 修改文件权限 ASP.NET MVC

.net - 排序列表中的部分键匹配 <string>

c++ - SFML/C++/Windows10 奇怪的消息?

c++ - 为什么 GetSystemMetrics() 返回这些值?

C#文本框光标定位

c# - 使用 C# 将 MemoryStream 转换为 FileStream?

c# - 加速 C#/.NET 应用程序的执行

.net - 从 Umbraco 4.7 中的 razor 宏渲染 ascx 用户控件