加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – BackgroundWorker:RunWorkerCompleted中的InvalidOperati

发布时间:2020-12-15 18:28:35 所属栏目:百科 来源:网络整理
导读:我有一个带有backgroundWorker的WinForm: using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using SEOTools.Utils;na
我有一个带有backgroundWorker的WinForm:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SEOTools.Utils;

namespace SEOTools.UI
{
    public partial class UIProgress : Form
    {
        public UIProgress(DoWorkEventHandler doWorkEventHandler,RunWorkerCompletedEventHandler runWorkerCompletedEventHandler)
        {
            InitializeComponent();
            this.backgroundWorker.WorkerReportsProgress = true;
            this.backgroundWorker.WorkerSupportsCancellation = true;
            this.backgroundWorker.DoWork += doWorkEventHandler;
            this.backgroundWorker.RunWorkerCompleted += runWorkerCompletedEventHandler;
        }

        public void Start()
        {
            var foo = SynchronizationContext.Current;
            backgroundWorker.RunWorkerAsync();
        }

        private void btnStop_Click(object sender,EventArgs e)
        {
            btnStop.Enabled = false;
            btnStop.Text = "Stopping...";
            backgroundWorker.CancelAsync(); 
        }

       private void backgroundWorker_ProgressChanged(object sender,ProgressChangedEventArgs e)
    {
        try
        {
            wdgProgressBar.Value = e.ProgressPercentage;
            if (this.Visible == false)
            {
                this.ShowDialog();
                this.Update();
            }
        }
        catch (InvalidOperationException) {} 
    }

        private void backgroundWorker_RunWorkerCompleted(object sender,RunWorkerCompletedEventArgs e)
        {
            this.Hide(); //Here I get a InvalidOperationException
            this.Dispose();
        }    
    }
}

我第一次运行它运行正常.但是第二次调用this.Hide()时我得到InvalidOperationException.

“Additional information: Cross-thread operation not valid: Control ‘UIProgress’ accessed from a thread other than the thread it was created on.”

奇怪的是第一次运行foo在Start()中是一个WindowsFormsSyncronizationContext,但在第二次尝试它是一个System.Threading.SyncronizationContext.

我正在编写的应用程序是一个ExcelDna插件.

编辑

Start()被调用如下:

UIProgress uiProgress = new UIProgress(
                delegate(object sender,DoWorkEventArgs args)
                {
                   ....
                },delegate(object sender,RunWorkerCompletedEventArgs args)
                    {
                       ...
                    }
            );
            uiProgress.Start();

解决方法

必须从在UI线程上运行的代码调用Start()方法,以允许BackgroundWorker正常运行.这不是你得到这个例外的时候.为您的方法添加保护代码,以便您可以诊断此事故:
public void Start()
    {
        if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA) {
            throw new InvalidOperationException("Bug! Code called from a worker thread");
        }
        backgroundWorker.RunWorkerAsync();
    }

现在,您可以在throw语句上设置断点,并使用调试器的“调用堆栈”窗口来查找发生这种情况的原因.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读