1

When my MainPage loads in my Windows Phone 7 application, it triggers a popup splash screen that includes a progress bar and a graphic in a usercontrol. After displaying the spash screen I do some work in a BackgroundWorker thread to load some resources while the spash displays. When the loading is done I dismiss the popup. This technique is well documented on WindowsPhoneGeek.

I noticed today that while this is working flawlessly when running in debug under Visual Studio, if I run the same build directly without the debugger connected, the splash screen animation and progress bar never appear and the DoWork() thread takes at least twice as long to execute the same operations. I can see that the MainPage constructor gets called as well as OnNavigatedTo, but the popup still does't display and the default jpg splash image remains on the screen, until the worker thread completes. Then the popup displays for < 1 second and the mainpage displays. Again, this all works flawlessly when debugging through VS 2010.

This is all in the Emulator, I don't have a device yet. I just noticed this today, and coincidently(?) I just updated the environment to 7.1 last night.

    // Constructor
    public MainPage()
    {
        InitializeComponent();

        IDictionary<string, object> state = Microsoft.Phone.Shell.PhoneApplicationService.Current.State;

        if (!state.ContainsKey(STATE_WAS_LOADED))
        {
            state[STATE_WAS_LOADED] = "LOADED";

            this.LayoutRoot.Visibility = System.Windows.Visibility.Collapsed;

            _popup = new Popup();
            _popup.Child = new NPGSplash();
            System.Diagnostics.Debug.WriteLine("{0}: Displaying Splash Popup", DateTime.Now.ToString("ss.ffff"));
            _popup.IsOpen = true;

            // Asynchronously load the biggest dataset
            StartLoadingData();
        }
    }

    private void StartLoadingData()
    {
        _worker = new BackgroundWorker();
        _worker.DoWork += new DoWorkEventHandler(_worker_DoWork);
        _worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_worker_RunWorkerCompleted);
        _worker.RunWorkerAsync();
    }

    void _worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        this.Dispatcher.BeginInvoke(() => 
        {
            System.Diagnostics.Debug.WriteLine("{0}: Splash RunWorkerCompleted", DateTime.Now.ToString("ss.ffff"));
            this.LayoutRoot.Visibility = System.Windows.Visibility.Visible;
            this._popup.IsOpen = false; 
        });
    }

EDIT:

I ended up buying a device on ebay this week to ensure that I don't release an app where I can't confirm that it works properly. I can confirm that whatever the problem is, it does NOT occur when running the application on the device. Good news. Still, I can't explain what appears to be an approximately 3-5 second pause in my application after the consrtuctor is called. I even changed my logic in the constructor to set a System.Windows.Threading.DispatcherTimer to fire in 100ms to kick off my logic. When this code executes, the constructor completes, but the timer doesn't tick for 3-5 seconds. Very odd, and only in the simulator when not attached to the debugger.

4

1 回答 1

0

这里的问题似乎是您从未将Popup控件附加到可视树。老实说,我不知道为什么这也可以与附加的调试器一起使用,但我要从你的代码中解释出来。

我认为您需要做的是将Popup控件添加为 XAML 中的元素,MainPage以便将其附加到可视树。

我要说的另一件事是,可能值得将所有数据加载代码移出构造函数并移入事件的覆盖OnNavigatedTo或处理程序中Loaded。一般来说,最好让构造函数尽可能简短和简单(是的,我很欣赏您使用后台工作程序来加载数据)。

于 2011-08-12T08:30:44.730 回答