【问题标题】:Exception : Cross-thread operation not valid: Control 'pgImportProcess(Progress Bar)' accessed from a thread other than the thread it was created on [duplicate]例外:跨线程操作无效:控制'pgImportProcess(进度条)'从一个线程访问,而不是它在[重复]上创建的线程
【发布时间】:2012-01-24 02:59:43
【问题描述】:

可能重复:
Cross-thread operation not valid: Control accessed from a thread other than the thread it was created on

如何纠正这个异常:

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

时捕获异常

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

【问题讨论】:

  • 请在尝试发布新问题时查找相关问题。那么你会发现其中一些问题:123

标签: c# multithreading


【解决方案1】:

您无法从不同的线程更新用户界面(如错误所示)。

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

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

在您尝试更新进度条中的属性时,您将需要使用此代码。

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      您需要使用 Dispatcher 才能进入 UI 的线程。

      如果你使用 WPF:

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

      【讨论】:

      • 我没有使用 WPF ,只是使用 windows 应用程序表单 (WAF)
      猜你喜欢
      • 2011-10-05
      • 2013-07-06
      • 1970-01-01
      • 2011-01-15
      • 1970-01-01
      • 2016-05-21
      • 2016-06-11
      相关资源
      最近更新 更多