简体   繁体   English

C#/ Winforms App冻结/滞后

[英]C#/Winforms App freezing/lagging

I have an Application in C#/Winforms that is basically used to run test for customers accounts in a specific order/setup. 我在C#/ Winforms中有一个应用程序,主要用于在特定的订单/设置中为客户帐户运行测试。 They are all tests run in browsers and so I built it so it would automate the process since there are about 10-12 tests that need to be ran everytime a customer account is pulled up. 它们都是在浏览器中运行的测试,因此我构建它以便自动化该过程,因为每次提取客户帐户时都需要运行大约10-12个测试。

Basically what happens is you input the account number then it runs the tests. 基本上会发生什么是您输入帐号然后它运行测试。

Here's a sample code. 这是一个示例代码。

public void startTestProcess()
    { 
        if (!cancelTests)
        {
            testRunning = true;
            var tabPage = createTabPage(banToRun, Convert.ToInt32(banToRun));
            loadingBox.Visible = true;
            mainTabControl.TabPages.Insert(0, tabPage);
            mainTabControl.SelectedTab = mainTabControl.TabPages[0];
            runTest(tabPage, banToRun);
            loadingBox.Visible = false;
        }
    }

private void runTest(TabPage t, string ban)
    {
        if (!cancelTests && !cancelCurrentOnly)
        {
            var tC = createInitialTabControl();
            t.Controls.Add(tC);
            int[] theTests = profileInfo.getSetList;
            for (int i = 0; i < theTests.Length; i++)
            {
                if (!cancelTests && !cancelCurrentOnly)
                {
                    var newTab = createTabPage(urlStrings.getName(theTests[i]), theTests[i]);
                    tC.TabPages.Add(newTab);
                    var webBrowser = createBrowser(urlStrings.getUrl(theTests[i], ban));
                    newTab.Controls.Add(webBrowser);
                    if (theTests[i] != 0 && theTests[i] != 1 && theTests[i] != 6
                        && theTests[i] != 11 && theTests[i] != 12)
                    {
                        if (!webBrowser.IsDisposed)
                        {
                            try
                            {
                                while (webBrowser.ReadyState != WebBrowserReadyState.Complete)
                                {
                                    Application.DoEvents();
                                }
                            }
                            catch
                            {
                                //Do Nothing
                            }
                        }
                    }
                    IntPtr pHandle = GetCurrentProcess();
                    SetProcessWorkingSetSize(pHandle, -1, -1);
                }
            }
        }
        if (cancelCurrentOnly)
        {
            cancelCurrentOnly = false;
        }
        banToRun = string.Empty;
        testRunning = false;

    }

So basically my question is, how can I optimize what I have in order to 所以基本上我的问题是,我怎样才能优化我拥有的东西

A. Reduce lag/freezing - Note: Already implemented a way of forcing garbage collection after each test is run. A.减少滞后/冻结 - 注意:在每次测试运行后,已经实施了一种强制垃圾收集的方法。 B. Improve performance of the WebBrowser controls possibly? B.可能提高WebBrowser控件的性能? - Already tried some webbrowser alternatives like WebKit for C# Wrapper (does not work on all tests due to some ajax based coding i believe) C. Maybe implement multi-threaded operations. - 已经尝试过一些web浏览器替代方案,比如WebKit for C#Wrapper(由于我认为基于ajax的编码,因此不适用于所有测试)C。也许实现多线程操作。 Not sure how i'd go about this without having cross-threaded exceptions thrown. 如果没有抛出跨线程异常,我不知道如何解决这个问题。

Thanks for your assistance. 谢谢你的协助。 If you have any other questions feel free to ask. 如果您有任何其他问题,请随时提出。

The lag / freezing issue is caused by you not using multiple threads; 滞后/冻结问题是由于您没有使用多个线程引起的; therefore all of the test runs are using the UI thread, so the UI cannot respond while the tests are being run. 因此,所有测试运行都使用UI线程,因此UI在运行测试时无法响应。

If the reason you are not using a backround worker(s) is that your are worried about having cross-threaded exceptions thrown, then you just need to make sure you are properly passing information between your threads (as opposed to avoiding multithreading altogether). 如果您不使用backround worker的原因是您担心抛出跨线程异常,那么您只需要确保在线程之间正确传递信息(而不是完全避免多线程)。

Update 更新

This question addresses the issue of updating the UI based on workers' progress. 问题解决了根据工作人员的进度更新UI的问题。

As a side note, you should not have to force garbage collection; 作为旁注,你不应该强迫垃圾收集; most of the time, this will actually decrease performance. 大多数情况下,这实际上会降低性能。 The garbage collector is specifically designed to collect when it has availability to do so (when the CPU is available). 垃圾收集器专门设计用于在可用时(当CPU可用时)收集。 Forcing it to run takes cycles away from the real work your app is trying to do. 强制它运行需要周期远离你的应用程序尝试的实际工作。

I see a lot of heavy lifting being performed in methods that also handle GUI, and therefore I assume that all of this is being done in the application's main thread (which will block while performing non-graphic operations related to that WebBrowser and other areas). 我看到在处理GUI的方法中执行了很多繁重的工作,因此我假设所有这些都是在应用程序的主线程中完成的(在执行与该WebBrowser和其他区域相关的非图形操作时会阻塞) 。

Try to refactor this application to run in multiple threads. 尝试重构此应用程序以在多个线程中运行。 The main thread should be available as much as possible to respond to user events. 主线程应尽可能地响应用户事件。 Background threads should do the heavy lifting of creating expensive objects, performing long-running read/write operations, etc. 后台线程应该繁重地创建昂贵的对象,执行长时间运行的读/写操作等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM