简体   繁体   中英

How to use Multi threading in my project?

I am practicing an OCR program using C#, I am not much of a coder so I am trying to find my way around.

1- I OCR some pdf files.

2- I see the output of the OCR .

3- I use UI buttons to browse and then click convert.

4- I have a progress bar on the UI but it does not visually upgrade, while when I log the progressBar.Value I see its numbers are updating.

So I searched around and I found that the issue is I should like stop the thread and create a new one for the Ui to visually update, but I really do not understand that, or even do not know how to do it.

Can someone please help me ? like baby steps.

Also I know I have copied and pasted like alot of code for you to see.

The case is the following:

1- class fmMain : Form has a progressBarIncrementation function, responsible for taking the increment value from a function in processFunctions class.

2- progressBarIncrementation function has progressBar.Value to be updated, I see its value updated.

3- But visually nothing is updated. I tried some threading code, but i do not understand it so.....

class processFunctions 
    {
        Thread newThread = Thread.CurrentThread;
        private string invoiceNameIndex = "";
        private string invoiceIBANIndex = "";
        private string invoiceNumberIndex = "";
        private string invoiceDateIndex = "";
        private string invoiceSubtotalIndex = "";
        private string invoiceVATIndex = "";
        private string invoiceTotalIndex = "";
        private string[] filePath;
        private string[] fileNamePDF;
        private int totalNumberOfFiles;

        private string InformationNeeded(string wholeRead, string ix)
        {

            string[] lines = wholeRead.Split(new[] { "\r\n", "\r", "\n", " " }, StringSplitOptions.None);
            if(ix.Contains(","))
            {
                string[] variableIndex = ix.Split(',');
                string name = "";
                for(int i =0; i < variableIndex.Length; i++)
                {
                    name += lines[Convert.ToInt32(variableIndex[i])]; 
                }
                return name;
            }

            return lines[Convert.ToInt32(ix)];
        }

        public void ocrFunction(string filePathOnly)
        {

            var Ocr = new AutoOcr();
            var Results = Ocr.ReadPdf(filePathOnly);
            var Barcodes = Results.Barcodes;
            var Text = Results.Text;
            string[] numbers = { invoiceNameIndex, invoiceIBANIndex, invoiceNumberIndex,
                invoiceDateIndex, invoiceSubtotalIndex, invoiceVATIndex, invoiceTotalIndex};
            string[] results = new string[numbers.Count()];

            for (int i = 0; i < numbers.Length; i++)
            {
                results[i] = InformationNeeded(Text, numbers[i]);
                Console.WriteLine(results[i]);
            }
            Results = null;
            Ocr = null;
            Barcodes = null;
            Text = null;

        }

        public int browseFile()
        {
            Thread.CurrentThread.SetApartmentState(ApartmentState.STA);
            OpenFileDialog ofd = new OpenFileDialog();
            int numberOfFilesToBeProcessed = 0;
            ofd.Filter = "PDF|*.pdf";
            ofd.Multiselect = true;
            string[] name = new string[2];

            if (ofd.ShowDialog() == DialogResult.OK)
            {
                numberOfFilesToBeProcessed = ofd.FileNames.Length;
                filePath = ofd.FileNames;
                fileNamePDF = ofd.SafeFileNames;
            }
            this.totalNumberOfFiles = ofd.FileNames.Length;
            return numberOfFilesToBeProcessed;
        }

        public void databaseReader()
        {

            string connectionString;
            SqlConnection connection;
            connectionString = ConfigurationManager.ConnectionStrings["OCR_App.Properties.Settings.LibraryConnectionString"].ConnectionString;


            for (int i = 0; i < fileNamePDF.Length; i++)
            {

                string fileNameFiltered = fileNamePDF[i].Replace(".pdf", "");

                using (connection = new SqlConnection(connectionString))
                using (SqlDataAdapter adapter = new SqlDataAdapter("SELECT * FROM invoicesTable WHERE invoiceRef = '" + fileNameFiltered + "'", connection))
                {
                    DataTable invoicesTable = new DataTable();
                    adapter.Fill(invoicesTable);

                    DataRow index = invoicesTable.Rows[0];

                    invoiceNameIndex = (index[1].ToString());
                    invoiceIBANIndex = (index[2].ToString());
                    invoiceNumberIndex = (index[3].ToString());
                    invoiceDateIndex = (index[4].ToString());
                    invoiceSubtotalIndex = (index[5].ToString());
                    invoiceVATIndex = (index[6].ToString());
                    invoiceTotalIndex = (index[7].ToString());

                    ocrFunction(filePath[i]);
                    //newThread.Start();
                    fmMain formFunctions = new fmMain();
                    //Thread.Yield();

                    //Thread thread = new Thread(() => formFunctions.ProgressBarIncrementation(progressBarIncrement()));
                    formFunctions.ProgressBarIncrementation(progressBarIncrement());

                }
            }
        }
        public int progressBarIncrement()
        {
            int incrementValue = 0;
            incrementValue = incrementValue + 100 / totalNumberOfFiles;
            //Console.WriteLine(incrementValue);
            return incrementValue;
        }
///////////////////////////////////////////////////////////////////
public partial class fmMain : Form
    {
        processFunctions processingMain = new processFunctions();
        ProgressBar NewprogressBar = new ProgressBar();
        private static int incrementbar = 0;

        public fmMain()
        {
            InitializeComponent();
        }

        [STAThread]
        private void BtnBrowse_Click(object sender, EventArgs e)
        //Browse the file needed to scan.
        {            
            int number = processingMain.browseFile();
            txtBoxFilePath.Text = number.ToString();
        }

        public void BtnConvert_Click(object sender, EventArgs e)
        {
            processingMain.databaseReader(); 
        }

        private void fmMain_Load(object sender, EventArgs e)
        {
        }

        private void txtBoxFilePath_TextChanged(object sender, EventArgs e)
        { 
        }

        private void NumberOfFilesToBeProcessed_Click(object sender, 
        EventArgs e)
        {
        }

        public void progressBar_Click(object sender, EventArgs e)
        {

            progressBar.Maximum = 100;
            NewprogressBar.Value = progressBar.Value;

        }
        public void ProgressBarIncrementation(int incrementValue)
        {
            //Thread.Yield();
            //Thread newThread = Thread.CurrentThread;

            incrementbar = incrementbar + incrementValue;
            progressBar.Visible = true;
            progressBar.Value += incrementbar;
            Thread thread = new Thread(() => progressBar.Value += incrementbar);
            Console.WriteLine(progressBar.Value);


            //progressBar.Value += incrementbar;

        }
    }

If you are needing the progress bar, you might want to consider creating an event to help report progress to your calling application. And you'll want to mark your function browseFile as async and do the following:

public async Task<int> browseFileAsync()
{
    await Task.Run(new Action(() => { 
    OpenFileDialog ofd = new OpenFileDialog();
    int numberOfFilesToBeProcessed = 0;
    ofd.Filter = "PDF|*.pdf";
    ofd.Multiselect = true;
    string[] name = new string[2];
        if (ofd.ShowDialog() == DialogResult.OK)
        {
            numberOfFilesToBeProcessed = ofd.FileNames.Length;
            filePath = ofd.FileNames;
            fileNamePDF = ofd.SafeFileNames;
        }
        this.totalNumberOfFiles = ofd.FileNames.Length;
        return numberOfFilesToBeProcessed;

              }));
    }

And then in your calling application do:

        private async void BtnBrowse_Click(object sender, EventArgs e)
    //Browse the file needed to scan.
    {          
        int number = await processMain.browseFileAsync();
        txtBoxFilePath.Text = number.ToString();
    }

I would also consider not calling a folder browser dialog from your class as this couples your class to a specific implementation. Rather, I would browse for the file from the GUI and pass the selected file(s) to the class.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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