FlowDocument from a different thread - "The calling thread cannot access this object because a different thread owns it."

  • Posted on: 7 July 2014
  • By: Michał Turecki

The FlowDocument along with most of the elements it contains inherits from DispatcherObject class. This means when constructed, it becomes linked to the thread in which it was constructed and causes several implications.

I'm sure such link was created for a reason - so that FlowDocument objects presented using WPF are not modified in a background thread as the updating is probably not implemented. I also won't debate on why objects contained in FlowDocument have no common, shared way of visiting them (IAddChild interface is helping with adding but something like IHaveChildren is not implemented).

Back to the topic - FlowDocument created by one thread cannot be used in another nor any of each one's inner objects. Or can't it?

One solution includes serializing a document in one thread and deserializing it in another (see this blog entry). This is a slow process as serialization is costly and serialization of a FlowDocument object with images and other graphical elements might not work at all unless XamlPackage format is used - and this one is even slower as requires ZIP compression/decompression.

Another is to create all FlowDocument objects on UI thread (see this SO article). Seems easy to do but what if there are thousand of objects which need to be added to a FlowDocument and at the same time user interface should stay responsive, even if it only needs to display a progress dialog ?

I found out another way to solve this problem, it is kind of hackish but seems to do the job for my needs:

public static void AttachToCurrentThread(this FlowDocument document)
{
	var dispatcher = Dispatcher.CurrentDispatcher;
	var field = typeof(DispatcherObject).GetField("_dispatcher", BindingFlags.NonPublic | BindingFlags.Instance);
	if(field == null)
	{
		throw new InvalidOperationException("_dispatcher property missing on DispatcherObject");
	}
	SetDispatcher(document, field, dispatcher, FlowDocumentVisitors);
}

private static readonly Func<object, object>[] FlowDocumentVisitors =
{
	x => (x is FlowDocument) ? ((FlowDocument) x).Blocks : null,
	x => (x is Section) ? ((Section) x).Blocks : null,
	x => (x is BlockUIContainer) ? ((BlockUIContainer) x).Child : null,
	x => (x is InlineUIContainer) ? ((InlineUIContainer) x).Child : null,
	x => (x is Span) ? ((Span) x).Inlines : null,
	x => (x is AnchoredBlock) ? ((AnchoredBlock) x).Blocks : null,
	x => (x is Paragraph) ? ((Paragraph) x).Inlines : null,
	x => (x is Table) ? ((Table) x).RowGroups : null,
	x => (x is Table) ? ((Table) x).Columns : null,
	x => (x is Table) ? ((Table) x).RowGroups.SelectMany(rg => rg.Rows) : null,
	x => (x is Table) ? ((Table) x).RowGroups.SelectMany(rg => rg.Rows).SelectMany(r => r.Cells) : null,
	x => (x is TableCell) ? ((TableCell) x).Blocks : null,
	x => (x is TableCell) ? ((TableCell) x).BorderBrush : null,
	x => (x is List) ? ((List) x).ListItems : null,
	x => (x is ListItem) ? ((ListItem) x).Blocks : null
};
	
private static void SetDispatcher(object item, FieldInfo field, object value, params Func<object, object>[] selectors)
{
	if(item is DispatcherObject)
	{
		var currentDispatcher = field.GetValue(item);
		if(currentDispatcher != null && currentDispatcher != value)
		{
			field.SetValue(item, value);
		}
	}
	if(item is IEnumerable)
	{
		foreach(var subItem in item as IEnumerable)
		{
			SetProperty(subItem, field, value, selectors);
		}
	}
	if(selectors != null)
	{
		foreach(var selector in selectors.Select(x => x(item)).Where(x => x != null))
		{
			SetProperty(selector, field, value, selectors);
		}
	}
}

Basically it just traverses FlowDocument and it's objects searching for DependencyObject instances and using reflection updates the _dispatcher private variable. This variable name can change in the future, the FlowDocument structure also can change so this solution can be considered not elegant or not stable but having said that DispatcherObject didn't change since .Net 3.5 and AttachToCurrentThread function can be easily adapted to handle different types of FlowDocument blocks and it's inner objects when those inherit from DispatcherObject.

If you are just reading this paragraph then feel free to leave some feedback, especially if I missed any important collections of DispatcherObject instances in the selectors array.

Update:

The previous code was expecting an IEnumerable as input and while this is fine and optimal (less calls) but not flexible enough to handle special cases well.
Unfortunately loading of a packed FlowDocument object, saved using XamlPackage format will fail on a non-STA thread ("The calling thread must be STA, because many UI components require this" exception thrown when TextRange.Load is called on a non-UI thread). This is a show-stopper for me so I can't use the code above anymore but it might become handy for someone not using Images.
I also updated it to support tables and lists and commented out style handling which I did not need (Styles are usually not tied to a thread anyway).
Actually the code can be generalized to handle any object, just change AttachToCurrentThread document argument type to object.

Update 2:
Some cosmetic changes and added a couple additional FlowDocument elements in a visitor.

Comments

Synkapton Viagra Fur Die Frau Flussig levitra disfuncion erectil Propecia Pelo Viagra Prices Usa Cytotec Sale

Vendita Kamagra France Dutasteride 0.5mg Avidart Sale Levitra Wann Einnehmen cialis 20mg price at walmart Cialis Ou Viagra Prix Provera Internet Low Price

Vendita Kamagra France Dutasteride 0.5mg Avidart Sale Levitra Wann Einnehmen cialis 20mg price at walmart Cialis Ou Viagra Prix Provera Internet Low Price

Cialis In Apotheke One Day Delivery Viagra viagra Zithromax Rx Dosage

Cialis In Apotheke One Day Delivery Viagra viagra Zithromax Rx Dosage

Cialis In Apotheke One Day Delivery Viagra viagra Zithromax Rx Dosage

I am from Slovenia. I can help with build this forum. Thanks for approved.

Jaz sem Slovenka. Lahko pomagam pri razvoju foruma.

I am from Slovenia. I can help with build this forum. Thanks for approved.

Jaz sem Slovenka. Lahko pomagam pri razvoju foruma.

I am from Slovenia. I can help with build this forum. Thanks for approved.

Jaz sem Slovenka. Lahko pomagam pri razvoju foruma.

I am from Slovenia. I can help with build this forum. Thanks for approved.

Jaz sem Slovenka. Lahko pomagam pri razvoju foruma.

Если вы стремитесь испытать удачу в азартных играх online, у вас стоит задача сорвать большой джекпот или у вас есть интерес просто отдохнуть, вы можете зайти на сайт онлайн казино. Невероятное количество женщин ныне ведут игру в автоматы на реальные денежные средства и играть в игральную слот-машину Sky Way также если вас интересуют онлайн слоты с быстрым выводом денег, советуем зайти на один из таких веб-сайтов. На avtomati-na-dengi.net вы сможете изучить правила игрового процесса, прочитать обзоры, где есть прилично интересных данных.

Если у вас есть цель развиваться в индустрии online игр, вам интересны разного рода игровые аппараты, вы сможете найти что-то интересное на ресурсе именно для вас! Вам не нужно вкладывать активы, нет необходимости выбирать только один слот. На сайте вы можете изучить информацию о различных играх. Вас ожидают отличные интересные сведения, которые доступны далеко не всем. Вы можете удваивать или утраивать бонусы. Прочитать сведения о том, как это должным образом делать – реально на ресурсе. Достаточно много людей, которые в 90х играли в казино в клубах, сейчас играют в онлайн casino.

На ресурсе вы можете ознакомиться с информацией о том, какие казино на деньги онлайн славятся и почему. Если вы не можете определиться с перечнем игровых аппаратов на деньги и играть в игральный слот Belissimo , на портале есть ряд статей, которые смогут вам помочь с выбором. Огромное количество разработчиков ПО, среди которых PlaySon, IgroSoft, Microgaming и другие, ныне создают игровые автоматы, которые становятся популярными в сжатые сроки.

Если вы хотите найти чисто информационно-обогревательный ресурс, вы можете кликнуть на avtomati-na-dengi.net, где вы можете просмотреть информацию о том, как быстро выводить активы. Если у вас в играх появляются сложности, вы не знаете что-то про слоты, информацию об этом вы также можете изучить на веб-странице. Чтобы вы знали, игровой аппарат «Панда» обладает особой тематикой. А если говорить про Fairy Land, вы сможете повеселиться не на шутку. Ведь лягушки в Fairy Land могут позволить выиграть ряд призов. Вы можете также узнать о том, какие слоты позволят выиграть больше денег. Игровые слоты сегодня безумно популярны. В них можно играть с любых мобильных гаджетов, будь то ОС Android или iOS. Вы можете вести игру на порталах также на разные суммы. На данный момент в казино вашему вниманию предоставляются самые крутые и азартные слоты.

Если вы давно желали найти надёжную и честную онлайн-платформу, вас интересуют классические автоматы, вы можете узнать детали о них на сайте. Ныне есть достаточно многофункциональных слотов. Если у вас есть интерес играть в многолинейные автоматы, вы можете делать это сегодня прямо из браузера. В online играх развлекаются ныне как парни, так и женщины. Надо отметить, что для того, чтобы вы могли положить на свой счет средства, вам необходимо сделать перевод, используя одну из платежных систем: Qiwi, WebMoney, Яндекс.Деньги. Вы также можете узнать, работает ли сервис с банковскими картами Visa и MasterCard и сделать банковский перевод. В основном, все транзакции очень быстро доходят. После пополнения счета, вы сможете наслаждаться идеальной графикой и вести игру в слоты разного жанра.

Одним из популярных слотов на данный момент считается Bratva. Этот слот завоевал доверие безумного количества игроков из разных стран СНГ. Необходимо отдельно подчеркнуть, что игроки могут получать также разного рода бонусы. Даже если в слотах вам не удалось сорвать джекпот, вы сможете отлично провести время и заработать крутой опыт. Вести игру в online казино лучше после регистрации. Это позволит обезопасить ваши данные и вашу игру.

Надо выделить, что на avtomati-na-dengi.net вы можете просмотреть сведения о том, как правильно общаться с технической поддержкой. Иногда бывают такие ситуации, когда менеджеры технической службы решают сложные вопросы, которые не могут решить пользователи самостоятельно. Если у вас трудности с мультивалютной картой или вы не можете оформить вывод финансов, вам также необходимо писать в службу технической поддержки. Менеджеры смогут разобраться в любых вопросах. На портале вы сможете найти перечень вопросов, на которые руководство любого онлайн казино должна в сжатые сроки предоставлять обратную связь. Если у вас возникают вопросы в игре в покер или рулетку, смело пишите в customer service и ожидайте обратную связь.

Если вы стремитесь испытать удачу в азартных играх online, у вас стоит задача сорвать большой джекпот или у вас есть интерес просто отдохнуть, вы можете зайти на сайт онлайн казино. Невероятное количество женщин ныне ведут игру в автоматы на реальные денежные средства и играть в игральную слот-машину Sky Way также если вас интересуют онлайн слоты с быстрым выводом денег, советуем зайти на один из таких веб-сайтов. На avtomati-na-dengi.net вы сможете изучить правила игрового процесса, прочитать обзоры, где есть прилично интересных данных.

Если у вас есть цель развиваться в индустрии online игр, вам интересны разного рода игровые аппараты, вы сможете найти что-то интересное на ресурсе именно для вас! Вам не нужно вкладывать активы, нет необходимости выбирать только один слот. На сайте вы можете изучить информацию о различных играх. Вас ожидают отличные интересные сведения, которые доступны далеко не всем. Вы можете удваивать или утраивать бонусы. Прочитать сведения о том, как это должным образом делать – реально на ресурсе. Достаточно много людей, которые в 90х играли в казино в клубах, сейчас играют в онлайн casino.

На ресурсе вы можете ознакомиться с информацией о том, какие казино на деньги онлайн славятся и почему. Если вы не можете определиться с перечнем игровых аппаратов на деньги и играть в игральный слот Belissimo , на портале есть ряд статей, которые смогут вам помочь с выбором. Огромное количество разработчиков ПО, среди которых PlaySon, IgroSoft, Microgaming и другие, ныне создают игровые автоматы, которые становятся популярными в сжатые сроки.

Если вы хотите найти чисто информационно-обогревательный ресурс, вы можете кликнуть на avtomati-na-dengi.net, где вы можете просмотреть информацию о том, как быстро выводить активы. Если у вас в играх появляются сложности, вы не знаете что-то про слоты, информацию об этом вы также можете изучить на веб-странице. Чтобы вы знали, игровой аппарат «Панда» обладает особой тематикой. А если говорить про Fairy Land, вы сможете повеселиться не на шутку. Ведь лягушки в Fairy Land могут позволить выиграть ряд призов. Вы можете также узнать о том, какие слоты позволят выиграть больше денег. Игровые слоты сегодня безумно популярны. В них можно играть с любых мобильных гаджетов, будь то ОС Android или iOS. Вы можете вести игру на порталах также на разные суммы. На данный момент в казино вашему вниманию предоставляются самые крутые и азартные слоты.

Если вы давно желали найти надёжную и честную онлайн-платформу, вас интересуют классические автоматы, вы можете узнать детали о них на сайте. Ныне есть достаточно многофункциональных слотов. Если у вас есть интерес играть в многолинейные автоматы, вы можете делать это сегодня прямо из браузера. В online играх развлекаются ныне как парни, так и женщины. Надо отметить, что для того, чтобы вы могли положить на свой счет средства, вам необходимо сделать перевод, используя одну из платежных систем: Qiwi, WebMoney, Яндекс.Деньги. Вы также можете узнать, работает ли сервис с банковскими картами Visa и MasterCard и сделать банковский перевод. В основном, все транзакции очень быстро доходят. После пополнения счета, вы сможете наслаждаться идеальной графикой и вести игру в слоты разного жанра.

Одним из популярных слотов на данный момент считается Bratva. Этот слот завоевал доверие безумного количества игроков из разных стран СНГ. Необходимо отдельно подчеркнуть, что игроки могут получать также разного рода бонусы. Даже если в слотах вам не удалось сорвать джекпот, вы сможете отлично провести время и заработать крутой опыт. Вести игру в online казино лучше после регистрации. Это позволит обезопасить ваши данные и вашу игру.

Надо выделить, что на avtomati-na-dengi.net вы можете просмотреть сведения о том, как правильно общаться с технической поддержкой. Иногда бывают такие ситуации, когда менеджеры технической службы решают сложные вопросы, которые не могут решить пользователи самостоятельно. Если у вас трудности с мультивалютной картой или вы не можете оформить вывод финансов, вам также необходимо писать в службу технической поддержки. Менеджеры смогут разобраться в любых вопросах. На портале вы сможете найти перечень вопросов, на которые руководство любого онлайн казино должна в сжатые сроки предоставлять обратную связь. Если у вас возникают вопросы в игре в покер или рулетку, смело пишите в customer service и ожидайте обратную связь.

I am ltonser. I need help. What can i do it?

I am ltonser. I need help. What can i do it?