我有一个动作,我需要在应用程序启动后大约3秒钟执行。我按如下方式实现了它:
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 :(得分:0)
如果它是丑陋的并不重要,你可以将它重构为一个方法,例如以Action
作为参数,这不会是一个大问题。
通过丑陋你可能意味着它看起来像坏代码我会建议使用普通线程(在你的行动之前使用Thread.Sleep
)而使用Dispatcher.Invoke
代替。我个人并不知道有任何关于此的最佳做法。这也可以很好地重构为一个采用Action
的简单方法。
如果您想要找到非阻塞等待there is a question,也可以找到它。
答案 1 :(得分:0)
以下是您可能感兴趣的类似内容:
How do we do idle time processing in WPF application?
这并不是您正在寻找的,因为它会在您的应用程序空闲时关闭您的窗口,但您可能会考虑在应用程序空闲后开始延迟。您可能会发现该链接比。
更有帮助答案 2 :(得分:0)
启动应用程序时,您是否没有特定的状态?通常,当应用程序准备好处理用户输入时,您希望SplashScreen关闭,而不是任意3秒。所以我建议关闭你的SplashScreen。
答案 3 :(得分: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
执行。 YMMV。
请注意,您也可以拨打app.Run()
而不是PumpDispatcherUntilAppExit()
,但我只是为了保持一致而这样做。