InvalidOperationException - объект используется в настоящее время в другом месте

Если объект, которому нужен доступ к контейнеру, является бобом в контейнере, просто реализуйте BeanFactoryAware или интерфейсы ApplicationContextAware.

, Если объекту вне контейнера нужен доступ к контейнеру, я использовал стандартный шаблон "одиночка" GoF для пружинного контейнера. Тем путем у Вас только есть один одиночный элемент в Вашем приложении, остальные - все одноэлементные бобы в контейнере.

26
задан Community 23 May 2017 в 11:47
поделиться

3 ответа

Внутри GDI + есть блокировка, которая предотвращает одновременный доступ двух потоков к битовой карте. Это не блокирующая блокировка, это блокировка типа «программист сделал что-то не так, я выдаю исключение». Ваши потоки бомбят, потому что вы клонируете изображение (== обращаетесь к растровому изображению) во всех потоках. Ваш поток пользовательского интерфейса бомбит, потому что он пытается нарисовать растровое изображение (== доступ к растровому изображению) в то же время, когда поток клонирует его.

Вам нужно ограничить доступ к растровому изображению только одним потоком. Клонируйте изображения в потоке пользовательского интерфейса перед запуском BGW, для каждого BGW требуется собственная копия изображения. Обновите свойство изображения PB в событии RunWorkerCompleted. Таким образом вы потеряете часть параллелизма, но это неизбежно.

50
ответ дан 28 November 2019 в 06:23
поделиться

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

Это означает, что в DoWork вы не должны обращаться ни к каким элементам управления (без использования Control.Invoke). Итак, здесь вы должны вызвать RunWorkerAsync, передавая клон вашего изображения. Внутри обработчика событий DoWork вы можете извлечь параметр из DoWorkEventArgs.Argument.

Только обработчики событий ProgressChanged и RunWorkerCompleted должны взаимодействовать с графическим интерфейсом пользователя.

1
ответ дан 28 November 2019 в 06:23
поделиться

Похоже, ваши BackgroundWorkers пытаются получить доступ к одним и тем же компонентам Windows Forms одновременно. Это объясняет, почему сбой является случайным.

Вам нужно убедиться, что этого не происходит, используя блокировку , возможно, так:

private object lockObject = new object();

algo1backgroundworker_DoWork()
{
    Image imgclone;
    lock (lockObject)
    {
        Image img = this.picturebox.Image;
        imgclone = img.clone();
    }

    //operate on imgclone and output it
}

Обратите внимание, что я проверяю, что imgclone установлен. local для этого метода - вы определенно не хотите использовать его для всех методов!

С другой стороны, один и тот же экземпляр lockObject используется всеми методами. Когда метод BackgroundWorker входит в свою секцию lock {} , другие, которые дошли до этой точки, будут заблокированы. Поэтому важно убедиться, что код в заблокированной секции работает быстро.

Когда вы приходите к «выводу» обработанного изображения, также будьте осторожны, чтобы убедиться, что вы не выполняете межпотоковое обновление пользовательского интерфейса. .

23
ответ дан 28 November 2019 в 06:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: