Operationcompleted had already been called in the operation and other calls are illegal. Background Worker

Asked

Viewed 44 times

0

I’m developing an application where I came across a mistake I’ve been consulting, but I couldn’t understand exactly how to fix it. In short:

I created a form that opens as Dialog and gives me the option to select a file .xlsx. It imports all values from the spreadsheet and while reading the values adds to the Mysql database.

I added the class BackgroundWork to carry out the operation counting process and return in a progressBar. But every time he executes one insert in the table when going to read the current position that is to pass the progress, returns the following message; inserir a descrição da imagem aqui

I’d like some help understanding where I’m going wrong. Follows code below.

public partial class ImportCFOPForm : Form
    {
        private FormServices FormServices { get; set; }
        private BackgroundWorker Worker { get; set; }
        private CFOPController Controller { get; set; }
        private CFOPForm CFOPForm { get; set; }
        private FormLoad FormLoad { get; set; }
        private int InitParmForm { get; set; }
        public string filePath { get; set; }

    public ImportCFOPForm(CFOPController _controller, Form _form)
    {
        InitializeComponent();
        SetController(_controller);
        SetCFOPForm((CFOPForm)_form);
        FormLoad = new FormLoad();
        InitValuesForm();
        RunDialog();
    }

    private void WorkerProgress_DoWork(object sender, DoWorkEventArgs e)
    {
        LoadSpreadsheetAsync();
    }

    private void WorkerProgress_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        ProgressBarDefault.Value = e.ProgressPercentage;
        LblValuePorcent.Text = $"{ProgressBarDefault.Value}%";
    }

    private void WorkerProgress_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        //display("");
    }

    private void ImportCFOPForm_MouseDown(object sender, MouseEventArgs e)
    {
        FormServices.MoveForm(this);
    }

    private void BtnOk_Click(object sender, System.EventArgs e)
    {
        if (InitParmForm.Equals(1))
        {
            LblIsValid.Visible = false;
            LblProgress.Visible = true;
            LblValuePorcent.Visible = true;
            ProgressBarDefault.Visible = true;
            BtnOk.Visible = false;
            WorkerProgress.RunWorkerAsync();
        }
        else
        {
            this.DialogResult = DialogResult.OK;
        }

    }

    private async void LoadSpreadsheetAsync() 
    {
        IExcelDataReader excelReader;
        FileStream stream = File.Open(this.filePath, FileMode.Open, FileAccess.Read);
        string[] returnPosition = new string[2];

        if (Path.GetExtension(this.filePath).ToUpper().Equals(ConstantValues.TYPE_XLS))
        {
            excelReader = ExcelReaderFactory.CreateBinaryReader(stream);
        }
        else
        {
            excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
        }

        var conf = new ExcelDataSetConfiguration
        {
            ConfigureDataTable = _ => new ExcelDataTableConfiguration
            {
                UseHeaderRow = true
            }
        };

        DataSet result = excelReader.AsDataSet(conf);
        var dataTable = result.Tables[0];

        //excelReader.Close();

        if (dataTable.Rows.Count > 0)
        {

            int totalProgress = dataTable.Rows.Count;

            try
            {
                for (var i = 0; i < totalProgress; i++)
                { 
                    WorkerProgress.ReportProgress((int)(i + 1 * 100 / totalProgress));

                    string input = dataTable.Rows[i][0].ToString().Trim();

                    if (!string.IsNullOrEmpty(input))
                    {
                        char[] charsToTrim = { '*', '.' };
                        input = input.TrimStart(charsToTrim);

                        int finalString = input.Length;
                        string cfopValue = $"{input.Substring(0, 1)}.{input.Substring(1, finalString - 1)}";
                        string description = dataTable.Rows[i][1].ToString();
                        string application = dataTable.Rows[i][2].ToString();

                        var db = new CFOPDB()
                        {
                            CFOPValue = cfopValue,
                            Description = description,
                            Application = application
                        };

                        if (!db.CFOPValue.Equals(string.Empty))
                        {
                            returnPosition = await Controller.Insert(db);

                            if (returnPosition[0].Equals(ReturnMsgVersionEnum.sucess.ToString())) 
                            {
                                Controller = SessionStorage.NewCFOPController();
                            }

                        }
                    }
                }
            }
            catch (Exception ex)
            {
                FormLoad.DialogSimpleMsg(
                            CFOPForm,
                            string.IsNullOrEmpty(ex.InnerException.Message)
                            ? ex.Message
                            : ex.InnerException.Message,
                            TypeMsgReturnEnum.ERRO.ToString(),
                            MessageBoxIcon.Error);
            }

            if (returnPosition[0].Equals(ReturnMsgVersionEnum.sucess.ToString()))
            {
                
                FormLoad.DialogSimpleMsg(
                            CFOPForm,
                            $"A planilha {stream.Name}, foi importada com sucesso.",
                            TypeMsgReturnEnum.SUCESSO.ToString(),
                            MessageBoxIcon.Information);
            }
            else
            {
                FormLoad.DialogSimpleMsg(
                                CFOPForm,
                                returnPosition[1],
                                TypeMsgReturnEnum.ERRO.ToString(),
                                MessageBoxIcon.Error);
            }
        }
    }

    private void InitValuesForm()
    {
        WorkerProgress.WorkerSupportsCancellation = true;
        WorkerProgress.WorkerReportsProgress = true;
        FormServices = new FormServices();
        InitParmForm = 1;
        LblIsValid.Visible = true;
        LblProgress.Visible = false;
        LblValuePorcent.Visible = false;
        ProgressBarDefault.Visible = false;
        BtnOk.Visible = true;
    }

    private void RunDialog()
    {
        OpenFileDialog openDialog = new OpenFileDialog();
        //openDialog.Filter = "*.xlsx";

        openDialog.Title = "Selecione o Arquivo";

        if (openDialog.ShowDialog() == DialogResult.OK)
        {
            this.filePath = openDialog.FileName;
        }
    }

    private void SetController(CFOPController _controller)
    {
        this.Controller = _controller;
    }
    
    private void SetCFOPForm(CFOPForm _cfopForm)
    {
        this.CFOPForm = _cfopForm;
    }

1 answer

0


The problem is that you are calling an asynchronous method within the backgroundWorker. When he is called, the backgroundWorker finalize its execution, and within LoadSpreadsheetAsync you call the ReporProgress (but the backgroundWorker has already completed its execution...)

what actually happens is that you start a new thread in backgroundWorker, and call an asynchronous method by starting another thread again.

remove the async option from Loadspreadsheetasync that should solve this problem

  • Good afternoon, Rovann Linhalis. Our perfect, thanks for the tip, I edited the Insert method as synchronous and fixed the Loadspreadsheet method and solved the problem. Thank you so much for the help.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.