【问题标题】:issues with BackGround worker across classes跨班级的后台工作人员的问题
【发布时间】:2015-02-22 00:04:45
【问题描述】:

这是我在这个论坛的第一个问题,希望它不会在某个地方重复,因为我已经搜索了将近 4 周的回复,但没有任何进展。

这是我的情况, 我正在开发一个需要执行大量后台操作的应用程序,因此我创建了 2 个 BKW,第一个用于从数据库加载数据并将其放入可观察的集合中,'无需报告进度或支持取消这个':

    private Boolean loadTestSteps()
    {
        // Create a background worker thread that  don't report progress and does not
        // support cancelation
        BackgroundWorker wk_LoadTestSteps = new BackgroundWorker();

        wk_LoadTestSteps.DoWork += new DoWorkEventHandler(wk_LoadTestSteps_DoWork);

        wk_LoadTestSteps.RunWorkerAsync();

        return true;
    }

可观察的集合类:

公共类 clsTestStep : DependencyObject { 公共静态 DependencyProperty TestStepProperty = DependencyProperty.Register( "TestStep", typeof(String), typeof(clsTestStep));

    public string TestStep
    {
        get { return (string)GetValue(TestStepProperty); }
        set { SetValue(TestStepProperty, value); }
    } and so on for the rest of items....

现在是主背景,应该做更长的操作,同时向主 UI 报告进度,像这样声明

    private void InitializeBackGroundWork()
    {
        _wk_StartTest = new BackgroundWorker();
        // Create a background worker thread that ReportsProgress &
        // SupportsCancellation
        // Hook up the appropriate events.
        _wk_StartTest.DoWork += new DoWorkEventHandler(_wk_StartTest_DoWork);
        _wk_StartTest.ProgressChanged += new ProgressChangedEventHandler
                (_wk_StartTest_ProgressChanged);
        _wk_StartTest.RunWorkerCompleted += new RunWorkerCompletedEventHandler
                (_wk_StartTest_RunWorkerCompleted);
        _wk_StartTest.WorkerReportsProgress = true;
        _wk_StartTest.WorkerSupportsCancellation = true;
        _wk_StartTest.RunWorkerAsync();
    }

在 do work 事件中,恰好在 foreach 循环中,我遇到了一个错误:您无法访问此对象,因为另一个线程拥有它:

    void _wk_StartTest_DoWork(object sender, DoWorkEventArgs e)
    {

        //Loop through each test step and perform Test 
        foreach (clsTestStep item in _testStep)
        {
            Thread.Sleep(200); 
            temp[0] = item.TestStep;
            temp[1] = item.Delay.ToString();
            temp[2] = item.NumberRepetition.ToString();
            temp[3] = item.Mode.ToString();

            //Report % of Progress, Test step Name,and the paragraph from Class PerformTest
            _wk_StartTest.ReportProgress(counter,
                temp[0]);
            counter += 1;

            _performTest.Fdispatcher(temp, out _paragraph);

            //_si.PgBarMax = Convert.ToDouble(_testStep.Count);

        }

        //Report completion on operation completed
        _wk_StartTest.ReportProgress(counter);

    }

请问我这里缺少什么,因为我的头会因搜索而爆炸!!!

【问题讨论】:

  • 已尝试使用 Dispatcher 访问 clsTestStep 项目中的信息,但没有成功: Application.Current.Dispatcher.BeginInvoke( DispatcherPriority.Background, new Action(() => temp[0] = item. TestStep //无法访问项目对象 :( ));

标签: wpf c#-4.0


【解决方案1】:

对于可能遇到此类问题的人^^ 最后我找到了一种访问类的方法,即使它不属于当前线程,这里有一篇很好的文章,逐步解释了如何做到这一点here

【讨论】:

    【解决方案2】:

    听起来您的 ObservableCollection 是由另一个线程创建并拥有的,因此您的 _wk_StartTest_DoWork 方法无法访问它。

    你的 _testStep 变量来自哪里?

    顺便说一下,在多线程环境中,当多个线程访问相同的数据时,您应该更喜欢使用 ConcurrentBag 类而不是 ObservableCollection。 ConcurrentBag 是线程安全的。

    【讨论】:

    • 你好 FloChanz 感谢您的回复^^,我的 _testStep 对象由来自 mysqlDataBase 的数据填充,并且 _testStep 也是 observablecollection。
    • 不,抱歉,我不明白为什么会出错。访问您的项目的 TestStep 属性时或之前是否崩溃?您可以尝试在 _testStep 变量上添加 ToList() 吗: foreach (clsTestStep item in _testStep.ToList())
    • 感谢 FloChanz 你的评论给了我一些想法 ^^
    猜你喜欢
    • 1970-01-01
    • 2015-12-07
    • 2014-03-12
    • 2011-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多