问题
The Prism application I have performs multiple startup tasks that can take a while and if some of those tasks fail to execute properly it will make the application functionally unusable. Because of this, I have a startup screen that displays before the Shell and shows a log of the status of each startup task. (The startup tasks are handled by a shared service in a module.) The screen includes a ProgressBar with IsIndeterminate set to True (at least while the startup tasks are running). I also include among the startup tasks that show in the displayed log the initializing of the modules themselves. (First task in log.)
The issue I have is that one of my modules loads a fairly large 3rd party library. I originally had this module just register all it's types and left actual resolution to Unity. However, this presented two issues: 1) When the user would reach the point where the view in this module would be loaded, the application would pause while it loaded this large library. 2) Some of the business logic in this module should be active before the user interacts with the view. So in my IModule implementation instead of calling RegisterType() for most of my services, I'm calling RegisterInstance. This is all well and good.
The problem is, now that this 3rd party library is being loaded up front when Unity creates all the services in this module, it takes a while for my modules initialization to finish. And the progress bar in my startup screen doesn't animate because the Dispatcher thread seems to be occupied loading up the modules.
Is there something I can do to have this slow loading module asynchronously load or similar so that the progress bar animates? It's not the end of the world if it isn't possible, but it'd be nice to have.
回答1:
You have (at least) two options:
- use a
SplashScreen - do module initialization on another thread
Splashscreen example:
internal class MyBootstrapper
{
// [...]
protected override void InitializeModules()
{
var splashScreen = new SplashScreen( "myLogo.png" );
splashScreen.Show( false );
try
{
base.InitializeModules();
}
finally
{
splashScreen.Close( TimeSpan.Zero );
}
}
}
Tasks example:
internal class MyBootstrapper
{
// [...]
protected override void InitializeModules()
{
Task.Run( () => base.InitializeModules() );
}
}
with this, you have to be careful that some services might unexpectedly not be created on the ui thread (e.g. EventAggregator) and those will behave strangely. If that happens, resolve them before kicking off the task that does the initialization.
来源:https://stackoverflow.com/questions/40596743/prism-module-loading-locks-up-dispatcher-thread-is-there-a-way-around-this