2011-07-30 36 views
2

作为我的应用程序启动过程的一部分,它检查数据完整性,如果它发现问题,它会向用户弹出一条消息,告诉他们可能需要一段时间修理东西。MessageBox.Show在应用程序启动早期导致应用程序终止

我使用MessageBox.Show显示消息。由于数据检查是从工作者线程完成的,因此我将切换到UI线程以进行该调用,然后设置ManualResetEvent以在用户确认消息时告知工作线程。

我在应用程序生命周期的早期从主应用程序类的构造函数中启动数据检查/加载,通过拆分工作线程(使用ThreadPool)。

当我用调试器运行,并显示消息时,应用程序只是等待输入。当我在没有调试器的情况下运行时,应用程序在显示对话框10秒后终止。

这10秒钟是一个很大的线索 - 它告诉我操作系统认为应用程序花了很长时间来初始化(操作系统杀死需要很长时间启动的应用程序)。

我认为我的MessageBox.Show在App.RootFrameNavigating有机会被调用之前阻塞了UI线程。

我的问题:

  • 难道我的声音诊断正确?
  • 我宁愿提前启动我的数据加载,因为它几乎完全是IO,除了这个消息框,并且越早我可以让我的模型加载,越好,但通常会延迟数据加载,直到后来在应用生命周期?
  • 其他意见/建议?我无法保证哪个页面将成为开始页面,因为应用程序可能会恢复到任何页面。我也在考虑让MessageBox.Show延迟本身,直到应用程序初始化,也许轮询一个由App.RootFrameNavigating设置的标志 - 这是否有意义?

回答

0

因此,我想到的解决方案仍然是从应用程序的构造函数中启动工作线程中的数据加载,但在我的我调用调用MessageBox.Show PhoneService的类ShowDialog方法,我检查,看看是否已经发生了初始导航:

private readonly ManualResetEvent _appInitialized = new ManualResetEvent(false); 

public void AppInitialized() 
{ 
    _appInitialized.Set(); 
} 


public void ShowDialog(string caption, string text, Action<MessageBoxResult> callback, MessageBoxButton button = MessageBoxButton.OKCancel) 
{ 
    _appInitialized.WaitOne(); 
    DispatcherHelper.CheckBeginInvokeOnUI(() => 
    { 
     var result = MessageBox.Show(text, caption, button); 

     if (callback != null) 
     { 
      callback(result); 
     } 
    }); 
} 
在我的应用程序类

然后:

private bool _firstNavigate = true; 
private void RootFrameNavigating(object sender, NavigatingCancelEventArgs e) 
{ 
    if (_firstNavigate) 
    { 
     _firstNavigate = false; 
     var navigationService = (NavigationService) sender; 
     navigationService.Navigated += NavigationServiceNavigated; 
    } 
     .... 


private void NavigationServiceNavigated(object sender, NavigationEventArgs e) 
{ 
    var navigationService = (NavigationService)sender; 
    navigationService.Navigated -= NavigationServiceNavigated; 
    PhoneServices.Current.AppInitialized(); 
} 

任何人看到任何与此问题进场?任何人都想出一个更好的方法?

+1

看起来这应该很好。如果从头开始一个应用,我可能会这样做。我会使用来自后台工作者的Mvvm-light消息到UI层而不是信号量。这将避免应用程序类的更改。 –

0

我认为你的问题是在应用程序构造函数中关闭工作线程的结果。在这种情况下,您应该使用适当的生命周期事件:PhoneApplicationService.Activated Event

+0

我不确定在启动我的数据加载的过程中有什么本质上的问题,只是它太早阻塞UI线程了......另外,如果应用程序启动时不激活激活它是平铺的 - 只有当应用程序在被置于休眠状态或墓碑之后才被激活时才会被调用。 – Damian

+0

我最初回答说你应该使用PhoneApplicatinService.Launching,但注意到文档中明确指出在这个事件中不加载数据。您可以随时查看是否已从Activated事件中加载相同效果的数据,这听起来像是理想的解决方案。这个问题可能源于这样的事实,即您在构造函数中执行的操作不应该 - 您正试图为尚未完成构建的应用程序加载数据。我建议你至少试一试,以排除这种可能性。 –

+0

我认为从隔离存储装载数据可以与应用程序启动的其余部分并行完成,只要它不会阻塞UI线程。如果不是,为什么不呢? – Damian

相关问题