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

时间:2018-01-23 09:12:58

标签: 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。< / p>

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

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

即使您的应用程序在后台执行了很多操作(您为应用程序分配的内容),但这对用户和Windows无关紧要。问题是,一旦你点击了应用程序的更多内容,被阻止的UI,Windows仍然会注意到这一点,并建议你关闭窗口,因为看起来应用程序被卡住了。

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

  

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

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

Application.DoEvents();

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