例外:跨线程操作无效:控制'pgImportProcess(进度条)'从其创建的线程以外的线程访问

时间:2011-12-20 03:39:41

标签: c# multithreading

  

可能重复:
  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

时捕获异常

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

3 个答案:

答案 0 :(得分:2)

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

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

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

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

答案 1 :(得分:1)

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

如果您使用WPF:

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

答案 2 :(得分:1)

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

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