2011-06-22 36 views
0

我的应用程序启动后需要大约3秒钟执行一个动作。在UI线程上实现延迟动作的最佳方式

internal static class Entry 
{ 
    private static SplashScreen splashScreen; 

    [STAThread] 
    internal static void Main() 
    { 
     ShowSplashScreen(); 
     StartApp(); 
    } 

    private static void ShowSplashScreen() 
    { 
     splashScreen = new SplashScreen("Splash.png"); 
     splashScreen.Show(false, true); 
    } 

    private static void StartApp() 
    { 
     var app = new App(); 

     //this, in particular, is ugly and more difficult to comprehend than I'd like 
     var dispatcherTimer = new DispatcherTimer(); 
     dispatcherTimer.Interval = TimeSpan.FromSeconds(3); 
     dispatcherTimer.Tick += delegate 
     { 
      CloseSplashScreen(); 
      dispatcherTimer.Stop(); 
     }; 
     dispatcherTimer.Start(); 

     app.Run(); 
    } 

    private static void CloseSplashScreen() 
    { 
     splashScreen.Close(TimeSpan.FromSeconds(1)); 
    } 
} 

我找到StartApp()代码比较难看,但一直没能炮制了一个更简洁的选择:我如下付诸实施。我在这里错过了一个常见的成语吗?

PS。是的,我知道SplashScreen有一个自动关闭选项。我不想使用它,主要是因为它在应用程序加载后立即关闭,这是我不想做的。

回答

0

如果它很丑陋并不重要,您可以将它重构为以Action为参数的方法,并且这不会成为问题。

正如你可能意味着它看起来像坏的代码,我会建议其采用Dispatcher.Invoke代替(你行动之前与Thread.Sleep)使用普通螺纹。我虽然没有意识到这方面的最佳做法。这也可以很好地重构成一个简单的方法,采取Action

如果你想要找到一个无阻塞的等待there is a question

0

这是类似的东西,你可能感兴趣的:

How do we do idle time processing in WPF application?

这不正是你所寻找的,因为它会立即关闭您的窗口,您的应用程序进入闲置状态,但你可以考虑在您的应用闲置后开始延迟。您可能会发现该链接有帮助。

0

当你的应用程序启动后,你没有一个特定的状态吗?通常,当您的应用程序准备好处理用户输入时,您希望SplashScreen关闭,而不是任意3秒。所以我会建议关闭你的SplashScreen。

0

这可能是我能想出的最好:

internal static class Entry 
{ 
    private static SplashScreen splashScreen; 
    private static App app; 

    [STAThread] 
    internal static void Main() 
    { 
     ShowSplashScreen(); 
     CreateApp(); 
     PumpDispatcherUntilPriority(DispatcherPriority.Loaded); 
     PumpDispatcherFor(TimeSpan.FromSeconds(2)); 
     CloseSplashScreen(); 
     PumpDispatcherUntilAppExit(); 
    } 

    private static void ShowSplashScreen() 
    { 
     splashScreen = new SplashScreen("Splash.png"); 
     splashScreen.Show(false, true); 
    } 

    private static void CloseSplashScreen() 
    { 
     splashScreen.Close(TimeSpan.FromSeconds(0.5)); 
    } 

    private static void CreateApp() 
    { 
     app = new App(); 
    } 

    private static void PumpDispatcherUntilPriority(DispatcherPriority dispatcherPriority) 
    { 
     var dispatcherFrame = new DispatcherFrame(); 
     Dispatcher.CurrentDispatcher.BeginInvoke((ThreadStart)(() => dispatcherFrame.Continue = false), dispatcherPriority); 
     Dispatcher.PushFrame(dispatcherFrame); 
    } 

    private static void PumpDispatcherFor(TimeSpan timeSpan) 
    { 
     var dispatcherFrame = new DispatcherFrame(); 

     using (var timer = new Timer(o => dispatcherFrame.Continue = false, null, (long)timeSpan.TotalMilliseconds, Timeout.Infinite)) 
     { 
      Dispatcher.PushFrame(dispatcherFrame); 
     } 
    } 

    private static void PumpDispatcherUntilAppExit() 
    { 
     var dispatcherFrame = new DispatcherFrame(); 
     app.Exit += delegate 
     { 
      dispatcherFrame.Continue = false; 
     }; 
     Dispatcher.PushFrame(dispatcherFrame); 
    } 
} 

我与扩展方法玩弄于Dispatcher,但最终发现他们不太直观。这是因为PushFrame()static,因此任何扩展方法都不会针对Dispatcher执行它们。因人而异。

请注意,您也可以拨打app.Run()而不是PumpDispatcherUntilAppExit(),但我只是为了保持一致性。

相关问题