У меня проблема, когда мой фоновый рабочий завершает работу, когда я в первый раз нажимаю вызывающую его кнопку, но второй раз, когда я нажимаю кнопку, возникает ошибка. Ошибка помечается целым числом, а не коллекцией.

Ошибка: «Этот тип CollectionView не поддерживает изменения своей SourceCollection из потока, отличного от потока Dispatcher». Строка кода: «t + = 1;» Может мне нужно определить фонового работника в другом месте? Вот часть кода.

       public P4LabelBatteryViewModel()
    {
        BatteryCheckerModel BatteryCheckerModel = new BatteryCheckerModel();

        worker.DoWork += worker_DoWork;
        worker.ProgressChanged += worker_ProgressChanged;
        worker.WorkerReportsProgress = true;
        worker.WorkerSupportsCancellation = true;
        worker.RunWorkerCompleted += Worker_WorkerCompleted;

    }
     private void checkOutRestults()
    {
        TotalFiles = 0;

        foreach (var _scripObject in ScriptCollection)
        {
            if (_scripObject.ScriptNameAdd != "")
            {
                TotalFiles += 1;
            }
        }

        if (ScriptCollection.Count > 0)
        {
                        _isrunning = true;
                        worker.RunWorkerAsync();
        }  
    }
       void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        var t = e.ProgressPercentage;
        NewBatteryFiles += 1;
    }

    void worker_DoWork(object sender, DoWorkEventArgs e)
    {
        ScriptModel _newFileResult = new ScriptModel();
        int t = 0;

        _newFileResult = CheckOutResults.CheckOutResultBatteryFiles(BatteryLocation, SelectedMachine.Machine);
        ScriptCollectionTemp.Add(_newFileResult);
        t += 1;

        foreach (ScriptModel _checkOutFile in ScriptCollection)
        {
           _newFileResult = CheckOutResults.CheckOutResultFiles(_checkOutFile, BatteryLocation, SelectedMachine.Machine);
           ScriptCollectionTemp.Add(_newFileResult);
           t += 1;
           worker.ReportProgress(t);
        }
        //worker.ReportProgress(t);
    }
    void Worker_WorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        foreach (ScriptModel _checkOutFile in ScriptCollectionTemp)
        {
            _checkOutFile.BackGround = new SolidColorBrush(Colors.LightGreen);
        }

        ScriptCollection = ScriptCollectionTemp;
    }
0
coolercargo 13 Мар 2018 в 07:41

2 ответа

Лучший ответ

Я изменил свой код следующим образом, и он работает во второй раз.

    void worker_DoWork(object sender, DoWorkEventArgs e)
    {
      BackgroundWorker worker = sender as BackgroundWorker;
        ScriptModel _newFileResult = new ScriptModel();
        ObservableCollection<ScriptModel> _scriptCollectionTemp = new ObservableCollection<ScriptModel>();

        for (int i = 0; i < ScriptCollection.Count; i++ )
        {
            _newFileResult = CheckOutResults.CheckOutResultFiles(ScriptCollection[i], BatteryLocation, SelectedMachine.Machine);
            _scriptCollectionTemp.Add(_newFileResult);
            worker.ReportProgress(_scriptCollectionTemp.Count);
        }
        ScriptCollection = _scriptCollectionTemp;
    }
-1
coolercargo 22 Мар 2018 в 14:33

Ни один элемент управления не захочет изменить их в потоке, отличном от потока пользовательского интерфейса. Так устроен мир

Не обращая внимания на другие проблемы, этот шаблон позволит вам обновлять пользовательский интерфейс из контекста, отличного от контекста пользовательского интерфейса.

Application.Current.Dispatcher.Invoke(
     () =>
        {
           // do any UI updates here
        });
1
TheGeneral 13 Мар 2018 в 04:47