开发者

c# help needed error

开发者 https://www.devze.com 2023-02-23 00:56 出处:网络
Cross-thread operation not valid: Control \'ocrTB\' accessed from a thread other than the thread it was created on.

Cross-thread operation not valid: Control 'ocrTB' accessed from a thread other than the thread it was created on.

This is the error i have. And below is my coding.

#region OCR(Tab5_Component)
    //When user is selecting, RegionSelect = true
    private bool RegionSelect = false;
    private int x0, x1, y0, y1;
    private Bitmap bmpImage;

    private void loadImageBT_Click(object sender, EventArgs e)
    {
        try
        {
            OpenFileDialog open = new OpenFileDialog();
            open.InitialDirectory = @"C:\Users\Shen\Desktop";

            open.Filter = "Image Files(*.jpg; *.jpeg)|*.jpg; *.jpeg";

            if (open.ShowDialog() == DialogResult.OK)
            {
                singleFileInfo = new FileInfo(open.FileName);
                string dirName = System.IO.Path.GetDirectoryName(open.FileName);
                loadTB.Text = open.FileName;
                pictureBox1.Image = new Bitmap(open.FileName);
                bmpImage = new Bitmap(pictureBox1.Image);
            }

        }
        catch (Exception)
        {

            throw new ApplicationException("Failed loading image");

        }
    }

    //User image selection Start Point
    private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
    {
        RegionSelect = true;

        //Save the start point.
        x0 = e.X;
        y0 = e.Y;
    }

    //User select image progress
    private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
    {
        //Do nothing it we're not selecting an area.
        if (!RegionSelect) return;

        //Save the new point.
        x1 = e.X;
        y1 = e.Y;

        //Make a Bitmap to display the selection rectangle.
        Bitmap bm = new Bitmap(bmpImage);

        //Draw the rectangle in the image.
        using (Graphics g = Graphics.FromImage(bm))
        {
            g.DrawRectangle(Pens.Red, Math.Min(x0, x1), Math.Min(y0, y1), Math.Abs(x1 - x0), Math.Abs(y1 - y0));
        }

        //Temporary display the image.
        pictureBox1.Image = bm;
    }

    //Image Selection End Point
    private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
    {
        // Do nothing it we're not selecting an area.
        if (!RegionSelect) return;
        RegionSelect = false;

        //Display the original image.
        pictureBox1.Image = bmpImage;

        // Copy the selected part of the image.
        int wid = Math.Abs(x0 - x1);
        int hgt = Math.Abs(y0 - y1);
        if ((wid < 1) || (hgt < 1)) return;

        Bitmap area = new Bitmap(wid, hgt);
        using (Graphics g = Graphics.FromImage(area))
        {
            Rectangle source_rectangle = new Rectangle(Math.Min(x0, x1), Math.Min(y0, y1), wid, hgt);
            Rectangle dest_rectangle = new Rectangle(0, 0, wid, hgt);
            g.DrawImage(bmpImage, dest_rectangle, source_rectangle, GraphicsUnit.Pixel);
        }

        // Display the result.
        pictureBox3.Image = area;
        pictureBox3.Image.Save(@"C:\Users\Shen\Desktop\LenzOCR\TempFolder\tempPic.jpg");

    }

    /*private void loadFolderBT_Click(object sender, EventArgs e)
    {
        folderBrowserDialog.ShowDialog();
        folderLocation.Text = folderBrowserDialog.SelectedPath;
    }*/

    private void ScanBT_Click(object sender, EventArgs e)
    {
        var folder = @"C:\Users\Shen\Desktop\LenzOCR\LenzOCR\WindowsFormsApplication1\ImageFile";

        DirectoryInfo directoryInfo;
        FileInfo[] files;
        directoryInfo = new DirectoryInfo(folder);
        files = directoryInfo.GetFiles("*.jpg", SearchOption.AllDirectories);

        exit = false;


        var processImagesDelegate = new ProcessImagesDelegate(ProcessImages2);
        processImagesDelegate.BeginInvoke(files, null, null);

        System.IO.File.Delete(@"C:\Users\Shen\Desktop\LenzOCR\TempFolder\tempPic.jpg");
    }

    private void ProcessImages2(FileInfo[] files)
    {
        var comparableImages = new List<ComparableImage>();

        //Invoke(setMaximumDelegate, new object[] { workingProgressBar, files.Length });

        var index = 0x0;

        var operationStartTime = DateTime.Now;

        foreach (var file in files)
        {
            if (exit)
            {
                return;
            }

            var comparableImage = new ComparableImage(file);
            comparableImages.Add(comparableImage);
            index++;
            //Invoke(updateOperationStatusDelegate, new object[] { "Processed images", workingLabel, workingProgressBar, index, operationStartTime });
        }

        //Invoke(setMaximumDelegate, new object[] { workingProgressBar, comparableImages.Count });

        index = 0;

        similarityImagesSorted = new List<SimilarityImages>();

        operationStartTime = DateTime.Now;

        var fileImage = new ComparableImage(singleFileInfo);

        for (var i = 0; i < comparableImages.Count; i++)
        {
            if (exit)
                return;

            var destination = comparableImages[i];
            var similarity = fileImage.CalculateSimilarity(destination);
            var sim = new SimilarityImages(fileImage, destination, similarity);
            similarityImagesSorted.Add(sim);
            index++;

            //Invoke(updateOperationStatusDelegate, new object[] { "Compared images", workingLabel, workingProgressBar, index, operationStartTime });
        }

        similarityImagesSorted.Sort();
        similarityImagesSorted.Reverse();
        similarityImages = new BindingList<SimilarityImages>(similarityImagesSorted);

        var buttons =
            new List<Button>
                {
                    ScanBT
                };

        if (similarityImages[0].Similarity > 85)
        {
            //MessageBox.Show("Similarity(%) : " + similarityImages[0].Similarity.ToString(), "Result", MessageBoxButtons.OK, MessageBoxIcon.Information);
            //MessageBox.Show("Similarity(%) : " + similarityImages[0].Destination.ToString(), "Result", MessageBoxButtons.OK, MessageBoxIcon.Information); 
            //MessageBox.Show("Similarity(%) : " + similarityImages[0].Source.ToString(), "Result", MessageBoxButtons.OK, MessageBoxIcon.Information);
            con = new System.Data.SqlClient.SqlConnection();
            con.ConnectionString = "Data Source=SHEN-PC\\SQLEXPRESS;Initial Catalog=CharacterImage;Integrat开发者_如何学Goed Security=True";
            con.Open();

            String getFile = "SELECT ImageName, Character FROM CharacterImage WHERE ImageName='" + similarityImages[0].Destination + "'";
            SqlCommand cmd2 = new SqlCommand(getFile, con);
            SqlDataReader rd2 = cmd2.ExecuteReader();

            while (rd2.Read())
            {
                ocrTB.Text = rd2["Character"].ToString(); // <<<<<< error occur here
            }
            con.Close();
        }
        else
        {
            MessageBox.Show("No character found!", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

    }
    #endregion

Any solution for this?


var processImagesDelegate = new ProcessImagesDelegate(ProcessImages2);
processImagesDelegate.BeginInvoke(files, null, null);

You are executing this delegate asynchronously in a different thread - are you sure that's what you want? That being the case you can use Control.Invoke() to update a UI control from another thread (the one your ProcessImages2 method is executed under) :

string text = rd2["Character"].ToString();
Action updateText = () => ocrTB.Text = text;
ocrTB.Invoke(updateText);

In general it would be easier to use a background worker to process your data and update it in the Completed event handler.


You cannot modify the UI in any thread other than the UI thread, ProcessImages2 in this example attempts to do this, you need to use Dispatcher.Invoke or just run ProcessImages2 in the same thread (i.e. don't do processImagesDelegate.BeginInvoke.

Also, posting a big chunk of code can be good, but try to give details on which line is throwing the error!


You need to marshal back to the other thread when trying to access controls on the UI from a new thread.. You can use Control.Invoke like such:

 someControl.Invoke((MethodInvoker)delegate
        {

            someControl.DoSomething();

        });
0

精彩评论

暂无评论...
验证码 换一张
取 消