线程工作不正常

本文关键字:不正常 工作 线程 | 更新日期: 2023-09-27 17:58:22

我制作了一个关于速记的程序,该程序工作正常,但在使用大型文本文件时没有响应。我需要实现它的线程。它尝试使用下面的代码,但仍然给了我同样的问题。实际上不知道我在哪里犯了错误。我还需要添加一个进度条,但不知道在哪里添加代码。

private void button3_Click(object sender, EventArgs e)
    {
        Thread myThread = new System.Threading.Thread(delegate()
        {
            RUN();
                for (int n = 0; n < 100; n++)
                {
                    Thread.Sleep(50);
                    progressBar1.BeginInvoke(new Action(() => progressBar1.Value = n));
                }
        });
        myThread.Start();
    }
    private void RUN()
    {
        if (this.InvokeRequired)
        {
            this.BeginInvoke((MethodInvoker)delegate()
            {
                int ascii;
                String xor;
                String text = textBox1.Text;
                if (textBox1.Text != "")
                {
                    Bitmap bitmap = (Bitmap)pictureBox1.Image;
                    Bitmap bmp = (Bitmap)pictureBox1.Image;
                    //richTextBox1.Text = "'n";
                    byte[] asciiBytes = Encoding.ASCII.GetBytes(textBox1.Text);// Convert the string into a byte[].
                    int x0 = 0, y0 = 0;
                    // Error checking, to see if text can fit in image
                    int imageSize = bitmap.Width * bitmap.Height;
                    if (imageSize - x0 * bitmap.Width - y0 < 8 * textBox1.Text.Length)
                    {
                        MessageBox.Show("Too Large");
                    }
                    for (int t = 0; t < textBox1.Text.Length; t++)
                    {
                        ascii = asciiBytes[t];
                        xor = program.binlength(Convert.ToString(ascii ^ 254, 2));
                        //richTextBox1.Text = richTextBox1.Text + xor + "'n";   
                        for (int i = 0; i < 8; i++)
                        {
                            // Check if y0 has exceeded image width
                            // so to wrap around to the new row
                            if (y0 == bitmap.Width)
                            {
                                x0++;
                                y0 = 0;
                            }
                            hide(bmp, bitmap, y0, x0, i,xor);
                            // x0, y0 are now the current pixel coordinates
                            //
                            // EMBED MESSAGE HERE
                            //
                            y0++;  // Move to the next pixel for the next bit
                        }
                    }
                    MessageBox.Show("" + (text.Length * 8));
                }
                else
                    MessageBox.Show("Text???");
            });
        }
    }
private void hide(Bitmap bmp, Bitmap bitmap,int y0,int x0,int i,string xor)
    {  
        Color colorpixel,newcolor;
        String pixR;
        colorpixel = bitmap.GetPixel(y0, x0);
        pixR = program.binlength(Convert.ToString(Convert.ToInt32(colorpixel.R), 2));
        newcolor = Color.FromArgb(Convert.ToByte(program.converttopixcel(xor, pixR, i), 2), colorpixel.G, colorpixel.B);
        bmp.SetPixel(y0, x0, newcolor);
        pictureBox2.Image = bmp;
    }

谢谢。

线程工作不正常

问题是:您在线程中运行您的东西,但线程代码是在UI线程的上下文中运行的,因为您使用this.BeginInvoke调用它。实际上,只有更新UI的部分才需要使用this.Invoke调用。

因此,当你认为是你的多线程时,你实际上不是。

也请使用this.Invoke,而不是this.BeginInvoke,因为对于BeginInvoke,您还需要在某个时刻调用EndInvoke,否则会泄漏内存/资源。

如何解决?我的建议:

在UI线程中为线程准备数据。也就是说:从文本框中获取文本,可能从图片框中获取图像,等等。将其传递给线程,可能作为ParameterizedThreadStartstate参数中State类的对象。

然后,让线程不做任何与UI相关的事情!没有消息框,没有图片框更新,什么都没有。线程结束时更新所有内容。

如果有效,您可以合并状态更新,然后以的形式调用

this.Invoke((Action)delegate()
{
    progressBar.Value = ...;
}

this.Invoke((Action)delegate()
{
    pictureBox.Image = ...;
}

看起来您正在通过BeginInvoke对UI线程进行所有思考。你实际上并没有在worker线程上做任何重要的工作。事实上,您在工作线程上所做的唯一一件事就是用一些Sleeps计数到100。它挂起并不奇怪。基本上:分为两个步骤:

  • 处理-直接在工作线程上执行
  • UI-之后执行此操作

有时,您可能会将两者混合使用,即在思考过程中通过BeginInvokeInvoke批量更新UI。不是每一行/项目/迭代-只是偶尔(例如,每1000行)