在 UI 线程上实现延迟操作的最简洁方法
我需要在应用程序启动后 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() 代码相当难看,但无法设计出更简洁的替代方案。我在这里缺少一个常见的习语吗?
附言。是的,我知道 SplashScreen
有一个自动关闭选项。我不想使用它,主要是因为应用程序加载后它就开始关闭,这是我不想做的。
I have an action I need to perform around 3 seconds after my app starts. I've implemented it as follows:
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));
}
}
I find the StartApp()
code rather ugly but have not been able to concoct a neater alternative. Is there a common idiom I'm missing here?
PS. Yes, I'm aware SplashScreen
has an auto-close option. I'm not wanting to use that mainly because it begins closing as soon as the app has loaded, which I don't want to do.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
以下是您可能感兴趣的类似内容:
如何我们在 WPF 应用程序中进行空闲时间处理?
这并不完全是您想要的,因为一旦您的应用程序空闲,它就会关闭您的窗口,但您可能会考虑在应用程序空闲后开始延迟。您可能会发现该链接很有帮助。
Here is something similar you might be interested in:
How do we do idle time processing in WPF application?
It's not exactly what you are looking for, because it will close your window as soon as your app goes idle, but you might consider to start your delay after your app went idle. You might find that link helpful than.
当您的应用程序启动完成时,您没有特定的状态吗?通常,您希望 SplashScreen 在应用程序准备好处理用户输入时关闭,而不是任意 3 秒。所以我建议关闭你的 SplashScreen。
Do you not have a specific state when your application is done starting? Normally you want your SplashScreen to close when your application is ready to handle user input, instead of an arbitrary 3 secs. So I would suggest to close your SplashScreen then.
这是我能想到的最好的办法:
我尝试了 Dispatcher 的扩展方法,但最终发现它们不太直观。这是因为
PushFrame()
是静态
,因此任何扩展方法实际上都不会针对其调用的Dispatcher
执行。 YMMV。请注意,您也可以调用
app.Run()
而不是PumpDispatcherUntilAppExit()
,但我这样做只是为了保持一致性。This is about the best I could come up with:
I toyed with extension methods for
Dispatcher
, but ultimately found them less intuitive. That's becausePushFrame()
isstatic
, so any extension methods don't actually execute against theDispatcher
they're invoked against. YMMV.Note that you could also call
app.Run()
instead ofPumpDispatcherUntilAppExit()
, but I just did that for consistency.如果它丑陋并不重要,您可以将其重构为采用
正如丑陋一样,您可能意味着它看起来像糟糕的代码,我建议使用普通线程(在操作之前使用
Thread.Sleep
),它使用Dispatcher.Invoke
反而。不过,我不知道这方面有任何最佳实践。这也可以很好地重构为采用Action
的简单方法。如果您想要非阻塞等待也可以找到一个关于此的问题。
Does not really matter if it is ugly, you can just refactor it into a method which takes an
Action
as parameter for example and that won't be much of a problem.As by ugly you probably meant that it looks like bad code i would suggest the use of a normal thread (with
Thread.Sleep
before your action) which usesDispatcher.Invoke
instead. I for one am not aware of any best practice regarding this though. This can also be nicely refactored into a simple method taking anAction
.If you want a non-blocking wait there is a question to be found about that as well.