异常:跨线程操作无效:控制“pgImportProcess(进度条)”从创建它的线程以外的线程访问

本文关键字:线程 创建 访问 无效 操作 控制 异常 pgImportProcess | 更新日期: 2023-09-27 18:18:15

可能的重复项:
跨线程操作无效:从创建它的线程以外的线程访问的控件

如何更正此异常:

Cross-thread operation not valid: Control 'pgImportProcess(ProgressBar control)' accessed from a thread other than the thread it was created on.

法典:

形式:

private void btnImport_Click(object sender, EventArgs e)
{
        if (CheckDataValidation() == false) return;
        if (MessageBox.Show("Do you want to import this file?", "Import", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No) return;
        Cursor.Current = Cursors.WaitCursor;
        //_blacklist.Process(pgImportProcess);
        Thread thread = new Thread(new ThreadStart(delegate { _blacklist.Process(pgImportProcess); }));
        thread.Start();
        if (!thread.IsAlive) thread.Abort();
        //ThreadStart process = delegate
        //                                {
        //                                    _blacklist.Process(pgImportProcess);
        //                                };
        //Thread threadProcess = new Thread(process);
        //threadProcess.Start();
        //if(!threadProcess.IsAlive) threadProcess.Abort();
    }

类:

public void Process(ProgressBar process)
{
        int same = 0, added = 0, updated = 0;
        OracleConnection connection = (OracleConnection)DbConnection.Instance();
        OracleTransaction transaction = connection.BeginTransaction(IsolationLevel.ReadCommitted);
        process.Step = 1;
        process.Minimum = 1;
        process.Maximum = _recordNumber;

        while (_csv.ReadNextRecord())
        {
            if (_csv[0] == null | _csv[0] == "") break;
            process.PerformStep();
            using (OracleCommand cmd = new OracleCommand(_sql, connection))
            {
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.CommandTimeout = 600;
                cmd.BindByName = true;
                switch (_fieldCount)
                {
                    case SdnName :
                        ImportBlacklistName(cmd);
                        break;
                    case SdnAddress:
                        ImportBlacklistAddress(cmd);
                        break;
                    case SdnAlt :
                        ImportBlacklistAlt(cmd);
                        break;
                }
                try
                {
                    cmd.ExecuteNonQuery();

                    switch (cmd.Parameters["message_out"].Value.ToString())
                    {
                        case "Added":
                            added += 1;
                            break;
                        case "Same":
                            same += 1;
                            break;
                        case "Updated":
                            updated += 1;
                            break;
                    }
                }
                catch (Exception error)
                {
                    transaction.Rollback();
                    MessageBox.Show(error.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }
        transaction.Commit();
        MessageBox.Show(String.Format("Total Record : {0} ; Added : {1} ; Updated : {2} ; Same : {3} !!!!",_recordNumber,added,updated,same), "Import successsfull", MessageBoxButtons.OK, MessageBoxIcon.Information);
        _recordNumber = 0;
        process.Value = 1;
        _csv.Dispose();
    }

它在 Process.step = 1 时捕获异常

如何解决这个问题?提前致谢

异常:跨线程操作无效:控制“pgImportProcess(进度条)”从创建它的线程以外的线程访问

您无法从其他线程更新用户界面(如错误状态所示(。

您需要调用该方法。任何简单的方法是通过 MethodInvoker:

        process.Parent.Invoke((MethodInvoker)delegate
        {
            process.Step = 1;
            process.Minimum = 1;
            process.Maximum = _recordNumber;
        });

每当尝试更新进度栏中的属性时,都需要使用此代码。

您需要

将 BeginInvoke 与委托一起使用,例如:

MethodInvoker yourAction = delegate
     { process.Step = 1;
    process.Minimum = 1;
    process.Maximum = _recordNumber; };
process.BeginInvoke(yourAction);

您需要使用调度程序进入UI的线程。

如果使用 WPF:

Dispatcher.BeginInvoke(new Action(()=>
{
    //place code here
}));