Random InvalidOperationException on application startup
I am experiencing a problem at application startup from time to time on production machines. It doesn't happen every time the application starts, and apparently it only happens on reboot. The application is started from login, added to HKLMSOFTWAREMicrosoftWindowsCurrentVersionRun.
Apparently, the problem is more frequent when resetting the machine, than during a reboot. Starting the application manually after it crashes is successful.
The following exception is thrown during startup:
Initialization of 'System.Windows.Controls.TextBlock' threw an exception. System.Windows.Markup.XamlParseException: Initialization of 'System.Windows.Controls.TextBlock' threw an exception. ---> System.InvalidOperationException: The calling thread cannot access this object because a different thread owns it. at System.Windows.Threading.Dispatcher.VerifyAccess() at System.Windows.Style.Seal() at System.Windows.StyleHelper.UpdateStyleCache(FrameworkElement fe,FrameworkContentElement fce, Style oldStyle, Style newStyle, Style& styleCache) at System.Windows.FrameworkElement.OnStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e) at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e) at System.Windows.Controls.TextBlock.OnPropertyChanged(DependencyPropertyChangedEventArgs e) at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args) at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType) at System.Windows.DependencyObject.InvalidateProperty(DependencyProperty dp) at System.Windows.FrameworkElement.UpdateStyleProperty() at System.Windows.FrameworkElement.OnInitialized(EventArgs e) at System.Windows.FrameworkElement.TryFireInitialized() at System.Windows.FrameworkElement.EndInit() at MS.Internal.Xaml.Runtime.ClrObjectRuntime.InitializationGuard(XamlType xamlType, Object obj, Boolean begin) --- End of inner exception stack trace --- at System.Windows.Markup.XamlReader.RewrapException(Exception e, IXamlLineInfo lineInfo, Uri baseUri) at System.Windows.Markup.WpfXamlLoader.Load(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean skipJournaledProperties, Object rootObject, XamlObjectWriterSettings settings, Uri baseUri) at System.Windows.Markup.WpfXamlLoader.LoadBaml(XamlReader xamlReader, Boolean skipJournaledProperties, Object rootObject, XamlAccessLevel accessLevel, Uri baseUri) at System.Windows.Markup.XamlReader.LoadBaml(Stream stream, ParserContext p arserContext, Object parent, Boolean closeStream) at System.Windows.Application.LoadComponent(Object component, Uri resourceLocator) at Exception.Occurs.At.Different.Origins.Between.Startup()
As seen from the StackTrace, there is something going on while updating style cache. I haven't been able to reproduce this on my own computer. There are no threads involved here while starting the application, but there are a few AppDomains. The origin of the exception is not always the same, but it is exactly the same from Application.LoadComponent(Object component, Uri resourceLocator)
Because our application needs to find the configuration file from a different location than the executable (..ProgramData....) depending on the OS, we use a separate AppDomain where we instruct it where to look for the configuration file, as we could not find any better solution of telling ConfigurationManager where to look for the file. It could of course, be related to this, though not necessarily. EDIT: ConfigurationManager.OpenMappedExeConfiguration Doesn't seem to work, as it won't refresh any user or application settings accessed through Properties.Settings.Default, etc.
Does anyone have any suggestions or recommendations on how to deal with this? Sorry I am not able to provide you with a sample to reproduce with.
That exception was because you are modifying a visual element from a thread that is not the visual one. I know this because in the first line of your exception it said:
Initialization of 'System.Windows.Controls.TextBlock' threw an exception. System.Windows.Markup.XamlParseException: Initialization of 'System.Windows.Controls.TextBlock' threw an exception. ---> System.InvalidOperationException: The calling thread cannot access this object because a different thread owns it.
All the rest of the exception doesn't matter. I think it is when you are loading the initial configuration, then you use other thread. The random behavior could be that some time you find the configuration before the TextBlock
control is loaded, so this times the exception will no be thrown.
To solve this please take a look to this question, and the last answer that I give (the one that use the SynchronizationContext
, that really works with WPF application that use several threads). If is not clear comment and I will write the solution here.
Hope this answer helps to find that random error, its are the worsts...
I'm not sure what is causing this exception but I there is a workaround to your problem.
Instead of creating a separate AppDomain
just for loading a different configuration file, you could use ConfigurationManager.OpenMappedExeConfiguration which allows you to load any .config file from anywhere in your local file system.
You use it like this:
//Map the new configuration file.
var configFileMap = new ExeConfigurationFileMap() { ExeConfigFilename = @"c:myOther.config"};
//Get the mapped configuration file
System.Configuration.Configuration config = ConfigurationManager.OpenMappedExeConfiguration(configFileMap, ConfigurationUserLevel.None);
Use config.GetSection()
to get specific sections for read-only use or directly the config
object to change the configuration at run-time.
And you will not need the different AppDomain which will mean faster startup time :)
摆脱用于指定配置文件的额外AppDomain,并将其替换为此链接中指定的方法来解决该问题。
链接地址: http://www.djcxy.com/p/30524.html上一篇: WPF崩溃不在我们的代码中