Объект в настоящее время используется где-то еще ошибка при использовании Paraller.For

Я пытаюсь распараллелить операцию с изображением, используя приведенный ниже код, но получаю ошибку One or more errors occurred.

Заглянув во внутреннее исключение, я вижу, что произошла ошибка {"Object is currently in use elsewhere."}.

Примечание: CoverImage и SecretImage - это Bitmaps

 Parallel.For(0, CoverImage.Width, x =>
            {
                for (int y = 0; y < CoverImage.Height; y++, SecretImageHeight++)
                {
                    Color coverImagesPixel = CoverImage.GetPixel(x, y);
                    Color secretImagesPixel = SecretImage.GetPixel(SecretImageWidth, SecretImageHeight);

                    int r = (coverImagesPixel.R & coverImageMask) + ((secretImagesPixel.R >> shift) & secretImageMask);
                    int g = (coverImagesPixel.G & coverImageMask) + ((secretImagesPixel.G >> shift) & secretImageMask);
                    int b = (coverImagesPixel.B & coverImageMask) + ((secretImagesPixel.B >> shift) & secretImageMask);

                    StegoImage.SetPixel(x, y, Color.FromArgb(255, r, g, b));
                }
                SecretImageHeight = 0;
                SecretImageWidth++;
            }
            );

Я пробовал использовать такой мьютекс:

mutex.WaitOne();
StegoImage.SetPixel(x, y, Color.FromArgb(255, r, g, b));
mutex.ReleaseMutex();

Но все равно безрезультатно (я получаю ту же ошибку).


person Rika    schedule 18.06.2015    source источник
comment
Какие типы бывают CoverImage и SecretImage? Используются ли они где-нибудь в приложении? Что происходит, когда вы обертываете доступ к ним в мьютексе - они тоже могут быть причиной проблемы.   -  person thorkia    schedule 18.06.2015
comment
Если вы следите за исключением, какая строка его вызывает? Я предполагаю, что либо SecretImage, либо CoverImage не являются потокобезопасными.   -  person flindeberg    schedule 18.06.2015
comment
@thorkia: они относятся к типу Bitmap. @ Флиндеберг: Он просто выделяет блок Parallel.For в целом   -  person Rika    schedule 18.06.2015
comment
@Hossein Вы пробовали перейти на непараллельный цикл, а затем добавить точку останова внутри цикла и пройтись по нему, чтобы увидеть, где возникает исключение? Я подозреваю, что Джон Скит прав, и вам нужно либо скопировать изображения в массив байтов, либо отправить к ним доступ в потоке пользовательского интерфейса.   -  person thorkia    schedule 18.06.2015
comment
возможный дубликат InvalidOperationException - объект в настоящее время используется где-то еще   -  person Henrik    schedule 18.06.2015
comment
@thorkia: Сейчас над этим работаем   -  person Rika    schedule 18.06.2015


Ответы (1)


Похоже, вы пытаетесь использовать API изображений из потоков, не связанных с пользовательским интерфейсом. Это плохая идея.

Я предлагаю вам скопировать изображение в массив байтов в потоке пользовательского интерфейса, затем запустить параллельный цикл for, который изменит массив, а затем воссоздать изображение из массива байтов.

person Jon Skeet    schedule 18.06.2015
comment
Если это WPF, другой вариант - использовать диспетчер и вызывать вызовы в потоке пользовательского интерфейса. - person thorkia; 18.06.2015
comment
@thorkia: Но OP намеренно использует Parallel.For для распараллеливания работы - пропуск каждого изображения через узкое место потока пользовательского интерфейса решит проблему. - person Jon Skeet; 18.06.2015