Я пытаюсь выяснить, как я могу скопировать DispatcherObject (в моем случае BitmapSource) в другой поток.
Вариант использования:
У меня есть приложение WPF, которое должно показывать окно в новом потоке (на самом деле это надстройка для Outlook, и мы должны сделать это, потому что Outlook имеет некоторые хуки в основном потоке пользовательского интерфейса и воровывает определенные горячие клавиши, которые нам нужны - «потерял» в переводе 'во взаимодействии с Outlook, WPF (который мы используем для пользовательского интерфейса) и Winforms (нам нужно использовать определенные элементы управления winforms, предоставляемые Microsoft).
С этим у меня есть моя реализация WPFMessageBox, которая настраивается путем установки некоторых статических свойств - и одним из них является BitmapSource для значка. Это используется для того, чтобы при запуске я мог установить WPFMessageBox.Icon один раз, и с тех пор каждый WPFMessageBox будет иметь одинаковый значок.
Проблема заключается в том, что BitmapSource, который назначен значку, является DispatcherObject, и при чтении он вызывает InvalidOperationException: «Вызывающий поток не может получить доступ к этому объекту, поскольку его принадлежит другой поток.».
Как я могу клонировать этот BitmapSource в реальный поток? У него есть методы Clone () и CloneCurrentValue (), которые не работают (они также выдают то же исключение). Мне также пришло в голову использовать originalIcon.Dispatcher.Invoke (выполните клонирование здесь), но Dispatcher в BitmapSource имеет значение null, и, тем не менее, я создал бы копию в неправильном потоке и все равно не смог бы использовать ее в моем. BitmapSource.IsFrozen == true.
Есть идеи, как скопировать BitmapSource в другой поток (без полной реконструкции его из файла изображения в новом потоке)?
EDIT:
Таким образом, замораживание не помогает: в конце концов, у меня есть BitmapFrame (Window.Icon в любом случае не использует никакой другой вид ImageSource), и когда я назначаю его как Window.Icon в другом потоке, даже если он заморожен, я get InvalidOperationException: «Вызывающий поток не может получить доступ к этому объекту, так как он принадлежит другому потоку». со следующей трассировкой стека:
WindowsBase.dll!System.Windows.Threading.Dispatcher.VerifyAccess() + 0x4a bytes
WindowsBase.dll!System.Windows.Threading.DispatcherObject.VerifyAccess() + 0xc bytes
PresentationCore.dll!System.Windows.Media.Imaging.BitmapDecoder.Frames.get() + 0xe bytes
PresentationFramework.dll!MS.Internal.AppModel.IconHelper.GetIconHandlesFromBitmapFrame(object callingObj = {WPFControls.WPFMBox.WpfMessageBoxWindow: header}, System.Windows.Media.Imaging.BitmapFrame bf = {System.Windows.Media.Imaging.BitmapFrameDecode}, ref MS.Win32.NativeMethods.IconHandle largeIconHandle = {MS.Win32.NativeMethods.IconHandle}, ref MS.Win32.NativeMethods.IconHandle smallIconHandle = {MS.Win32.NativeMethods.IconHandle}) + 0x3b bytes
> PresentationFramework.dll!System.Windows.Window.UpdateIcon() + 0x118 bytes
PresentationFramework.dll!System.Windows.Window.SetupInitialState(double requestedTop = NaN, double requestedLeft = NaN, double requestedWidth = 560.0, double requestedHeight = NaN) + 0x8a bytes
PresentationFramework.dll!System.Windows.Window.CreateSourceWindowImpl() + 0x19b bytes
PresentationFramework.dll!System.Windows.Window.SafeCreateWindow() + 0x29 bytes
PresentationFramework.dll!System.Windows.Window.ShowHelper(object booleanBox) + 0x81 bytes
PresentationFramework.dll!System.Windows.Window.Show() + 0x48 bytes
PresentationFramework.dll!System.Windows.Window.ShowDialog() + 0x29f bytes
WPFControls.dll!WPFControls.WPFMBox.WpfMessageBox.ShowDialog(System.Windows.Window owner = {WPFControlsTest.MainWindow}) Line 185 + 0x10 bytes C#