Передача данных из потока в Image

 
0
 
.NET
ava
vikaz | 24.10.2011, 20:41
Всем привет! Возник вопрос. У меня есть пример для работы с один SDK. И там присутствуют подобные функции, как ниже:


private void UpdateScreenImage(Bitmap hBitmap)
{
if (!this.Dispatcher.CheckAccess())
{
this.Dispatcher.Invoke(_setImageCallback = UpdateScreenImage, new object[] { hBitmap });
}
else
{
BitmapSource bmp1 = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(hBitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());

PictureFingerPrint.Source = bmp1;
}
}


private void OnTakeOff(FTR_PROGRESS Progress)
{
this.SetStatusText("Take off finger from device, please...");
}


private void SetStatusText(string text)
{
if (m_bExit) return;

if (!this.Dispatcher.CheckAccess())
{
this.Dispatcher.Invoke(_setTextCallback = SetStatusText, new object[] { text });
}
else
{
this.txtMessage.Text = text;
}
}


Как я понимаю, условие if (!this.Dispatcher.CheckAccess())
позволяет изменить состояния контрола из потока его (контрол) не создававшего. Я для себя решил, что мой класс адаптер будет работать только в WPF приложении.

Вопрос, можно ли подобные функции переложить на привязку данных? Т.е. функция UpdateScreenImage
будет иметь сл. вид:


private void UpdateScreenImage(Bitmap hBitmap)
{
BitmapSource bmp1 = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(hBitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
Bitmap = bmp1;
}


, где Bitmap:


public Bitmap Bitmap
{
get { return _bitmap; }
set
{
_bitmap = value;
OnPropertyChanged("Bitmap");
}
}


Ну а Image будет иметь сл. вид:


<Image Source="{Binding Bitmap}"/>


Правильно ли все это? Или это в корне неверный подход и нужно делать по другому?


ЗЫ. Компилятор, все же, выдает ошибку:"Вызывающий поток не может получить доступ к данному объекту, так как владельцем этого объекта является другой поток."
Хотя я так же через DataBinding, обновляю данные в контроле TextBox, и там таких проблем не возникает. Все работает как часы. :(

Может есть у кого-то мысли по этому поводу? Заранее спасибо!
Ответы (6)
ava
Gvozdin | 25.10.2011, 06:50 #
Если работа идет не в UI потоке, то этого ни кто кроме вас изменить не сможет. Dispatcher.Invoke как раз и ставит вызов в очередь UI потока.

Весь код который общается с WPF должен делать это в UI потоке.

Чем не устраивают Dispatcher.Invoke?
ava
vikaz | 25.10.2011, 07:07 #
Цитата


Чем не устраивают Dispatcher.Invoke?



Они меня устраивали, когда я напрямую из кода обращался к контролу.
Но как только я стал исрользовать Property для переброски значения, он перестал меня удовлетворять, так как ошибка осталась.
Возможно что-то делаю не так.
но в новом классе, я не могу использовать вот такой код:

this.Dispatcher.CheckAccess()

Могу только вот так:

Dispatcher.CurrentDispatcher.CheckAccess()

Но он всегда выдает true
ava
Gvozdin | 25.10.2011, 18:48 #
Давайте конкретно, на какой строке кода падает?

Dispatcher.CurrentDispatcher.CheckAccess() естественно вернет true, тк это диспетчер привязанный к текущему потоку, если его нет то он создается.

Почему this.Dispatcher не можете использовать? Передавайте диспетчер в качестве параметра метода, или вы в любом месте WPF приложения можете использовать Application.Current.Dispatcher, тк UI поток обычно один, то и диспетчер всегда будет нужный.
ava
vikaz | 26.10.2011, 18:50 #
Gvozdin, спасибо! Передал Dispatcher в мой класс и там его проверяю. Прокатило. СПС!
ava
Frostiboy | 07.11.2011, 14:13 #
А это единственный способ?
ava
Gvozdin | 07.11.2011, 15:49 #
Единственный способ чего?

Просто доступ к объектам WPF возможен только из UI потока.
Зарегистрируйтесь или войдите, чтобы написать.
Фирма дня
Вы также можете добавить свою фирму в каталог IT-фирм, и публиковать статьи, новости, вакансии и другую информацию от имени фирмы.
Подробнее
Участники
advanced
Отправить