线程无法正常工作

时间:2014-04-14 07:39:30

标签: c# multithreading

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

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;
    }

谢谢。

2 个答案:

答案 0 :(得分:1)

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

因此,当您认为您的多线程时,实际上并非如此。

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

如何解决?我的建议是:

在UI线程中准备线程的数据。即:从文本框中获取文本,也可以从图片框中获取图像等。将其传递给线程,可以作为State state类中ParameterizedThreadStart类的对象。

然后,让线程与UI相关的 nothing !没有消息框,没有更新图片框,没有。线程结束时更新所有内容。

如果可行,您可以合并状态更新,然后以

的形式调用
this.Invoke((Action)delegate()
{
    progressBar.Value = ...;
}

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

答案 1 :(得分:0)

看起来你正在通过BeginInvoke对UI线程进行所有思考。你实际上并没有在工作线程上做任何有意义的工作。事实上,你在工作线程上做的唯一事情就是用一些Sleep来计算到100。它挂起来应该不足为奇。基本上:将其分为两个步骤:

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

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