簡體   English   中英

c# - 按下按鈕后形成“滯后”

[英]c# - Form "lags" after button being pressed

我對我制作的游戲進行了擴展,當您按下“搜索像素”時,它會自動按下一個按鈕,但每次按下按鈕時,無論成功還是失敗,應用程序的內存都會增加大約 30 兆字節。 從 4.5 MB 開始,然后一旦單擊按鈕,它就會上升到 33.3 MB,這里是代碼


    {

        public Form1()
        {
            InitializeComponent();
        }

        private const UInt32 MOUSEEVENTF_LEFTDOWN = 0x0002;
        private const UInt32 MOUSEEVENTF_LEFTUP = 0x0004;

        [DllImport("user32.dll")]
        private static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint dwData, uint dwExtraInf);

        [DllImport("user32.dll")]
        private static extern bool SetCursorPos(int x, int y);

        private void OnButtonSearchPixelClick(object sender, EventArgs e)
        {
            // 01. get hex value from input field
            string inputHexColorCode = textBox1.Text;
            SearchPixel(inputHexColorCode);
        }

        private bool SearchPixel(string hexcode)
        {

            // Take an image from the screen
            // Bitmap bitmap = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height); // Create an empty bitmap with the size of the current screen 

            Bitmap bitmap = new Bitmap(SystemInformation.VirtualScreen.Width, SystemInformation.VirtualScreen.Height); // Create an empty bitmap with the size of all connected screen 

            Graphics graphics = Graphics.FromImage(bitmap as System.Drawing.Image); // Create a new graphics objects that can capture the screen

            graphics.CopyFromScreen(0, 0, 0, 0, bitmap.Size); // Screenshot moment → screen content to graphics object

            Color desiredPixelColor = ColorTranslator.FromHtml(hexcode);

            // Go one to the right and then check from top to bottom every pixel (next round -> go one to right and go down again)
            for (int x = 0; x < SystemInformation.VirtualScreen.Width; x++)
            {
                for (int y = 0; y < SystemInformation.VirtualScreen.Height; y++)
                {
                    // Get the current pixels color
                    Color currentPixelColor = bitmap.GetPixel(1550, 412);

                    // Finally compare the pixels hex color and the desired hex color (if they match, we found a pixel)
                    if (desiredPixelColor == currentPixelColor)
                    {
                        DoubleClickAtPosition(1387, 414);

                        return true;
                    }

                }
            }

            return false;
        }

        private void DoubleClickAtPosition(int posX, int posY)
        {
            SetCursorPos(posX, posY);

            Click();
            Thread.Sleep(250);
            Click();
        }

        private new void Click()
        {
            mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
            mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
        }
    }
}

此代碼來自我觀看的視頻。 如果您需要我做任何事情,例如發布視頻或發布任何其他代碼,請告訴我,我真的需要幫助。 我還想說,我對 C# 編碼真的很陌生。

解釋

Windows 窗體使用單線程單元模型。 這意味着 Windows 窗體中的所有內容,從呈現到處理 Windows 消息(如鼠標和鍵盤事件),都發生在單個線程中。

您可能已經注意到,在所有 WinForms 應用程序中,您都可以在Program.cs看到[STAThreadAttribute] “STA”代表“單線程公寓”。

因為 WinForms 在單線程單元中運行,所以您在 WinForms STA 線程中運行的任何密集代碼都會阻止 WinForms 呈現您的表單並處理其鼠標和鍵盤事件,因為它一次只能做一件事。

解決方案

此處的解決方案是在 WinForms STA 線程的單獨線程中運行您的密集SearchPixel()函數。

有很多方法可以實現這一點,例如BackgroundWorker或 hard Thread 然而,最簡單,最容易被接受的方法是使用一個Task后自動推遲到一個線程池。

這就像更改代碼一樣簡單:

private void OnButtonSearchPixelClick(object sender, EventArgs e)
{
    // 01. get hex value from input field
    string inputHexColorCode = textBox1.Text;
    Task.Run(() => {
        SearchPixel(inputHexColorCode);
    });
}

警告

由於您的代碼將在 WinForms 的 STA 線程以外的線程中運行,因此在不執行調用的情況下無法與 WinForms 正在使用的任何對象進行交互。

例如:

Task.Run(() => {
    label1.Text = "Test";
});

將導致InvalidOperationException ,因為您正在嘗試訪問 WinForms 希望只能在其單線程單元中訪問的對象。

您必須告訴 STA 線程調用一個操作,這將導致代碼在 STA 線程中運行。 像這樣:

Task.Run(() => {
    //Code in here will run in a thread pool

    this.Invoke((Action)delegate {
        //Code in here will run in the STA thread
       label1.Text = "Test";
    });
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM