There is an application with a very large visual tree. For some tasks, I implemented a mechanism that allows you to memorize the entire visual tree into a set of xml files.

I would like to speed up this mechanism. Now it works for independent parts of the interface, so I decided to put the recording of each interface part in the xml file into a separate stream.

The problem is to traverse the visual tree from a non-UI thread. WPF does not allow a third-party thread to access an item that it does not own ( InvalidOperationException ).

In such situations, I usually use Dispatcher.Invoke or Dispatcher.BeginInvoke . In the case of this task, this does not make sense, because by delegating execution through these methods everything will still be executed in the same (interest) stream, and I will not get any performance gain.

Question

Is it possible in some way to bypass the visual tree from several threads at once? Perhaps someone faced with such a task? I would be grateful for any suggestions and help.

UPD:

Most of the time it takes to get the list of properties from DependencyObject, the code to get the list of properties:

private static List GetDependencyProperties (DependencyObject obj)

{ List<DependencyProperty> result = new List<DependencyProperty>(); PropertyDescriptorCollection attCollect = TypeDescriptor.GetProperties(obj, new Attribute[] { new PropertyFilterAttribute(PropertyFilterOptions.All) }); foreach (PropertyDescriptor pd in TypeDescriptor.GetProperties(obj, new Attribute[] { new PropertyFilterAttribute(PropertyFilterOptions.All) })) { DependencyPropertyDescriptor dpd = DependencyPropertyDescriptor.FromProperty(pd); if (dpd != null && _filter.IsValidProperty(dpd.DependencyProperty.Name, obj.GetType().Name, dpd.DependencyProperty.OwnerType.Name)) { result.Add(dpd.DependencyProperty); } } return result; } 

_filter is a wrapper over a Dictionary that stores a list of excluded properties.

  • No, this is not possible, WPF is single-threaded. It seems to me that you approach the task incorrectly. Background work should be a model task, not a presentation. Are you using MVVM? If so, upload work to the model, send updates to the VM, and let View pick them up through bindings. - VladD
  • This is not a task for MVVM. I need to go around the visual tree and get a set of xml-files as quickly as possible. It is necessary for checking in automatic tests of the application. The main job is to take a list of all DependencyProperty from each UIElementa and fill in the attributes of the XML node. Yes, it seems that there really are no means to do this in multithreaded mode ... - Druuus
  • If this is indeed the task of the UI-level, then the answer, apparently, is negative. However, for automated tests, speed should not be essentially critical. - VladD
  • But you can at least separate the record in the file in the background thread. In the main stream, you can simply create the desired object tree, and its processing / recording carry in the background. This may not speed up the process, since the volume of recorded information is the same. Acceleration will be only if you have parallelized wood processing along the way. - VladD
  • On the other hand, something you are doing wrong. A visual tree can't be so huge, because WPF can somehow handle it? Maybe your workaround is slow by itself and can be speeded up? For example, maybe you use reflection and do not cache the results. Show your code. - VladD

0