0
votes

this is my first question in this forum, hope it will not be duplicated somewhere because i have searched for the respons for almost 4 weeks without making any progress.

here is my situation, im developing an application that need to do a lot of background operation, for that reason i creat 2 BKW, the first one used to load data from a DB and put it inside an observable collection , 'no need to report progress or support cancelation for this one' :

    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;
    }

observable collection class :

public class clsTestStep : DependencyObject { public static 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....

now the main backGround that should do the longer operation and in the same time report the progress to the main UI ,declared like so

    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();
    }

in the do work events, exactly in the foreach loop i encontered an error saying : you cannot access this object because another thread own it :

    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);

    }

what im missing here please, because my head is gonna explod from searching !!!

2
have tried to use Dispatcher to access info in clsTestStep items but with no luck : Application.Current.Dispatcher.BeginInvoke( DispatcherPriority.Background, new Action(() => temp[0] = item.TestStep //cannt access to item object :( )); - Badre Arras

2 Answers

0
votes

It sounds like your ObservableCollection is created and so owned by an other thread so your _wk_StartTest_DoWork method can't access it.

Where your _testStep variable comes from ?

By the way, in a multithread environment when many thread access the same data you should prefer the use of ConcurrentBag class instead of an ObservableCollection. ConcurrentBag is thread safe.

0
votes

for the ones that may enconter this kind of problem ^^ finnaly i have found a way to acess class even if its not owned by the current thread here a nice article explaining step by step how to do this here