加载时显示 C# 延迟模式对话框,同时允许继续执行

Posted

技术标签:

【中文标题】加载时显示 C# 延迟模式对话框,同时允许继续执行【英文标题】:C# Delay Modal Dialog showing on Load, whilst allowing execution to continue 【发布时间】:2009-08-17 22:29:11 【问题描述】:

我有一个通过静态方法显示的表单。

这个静态方法在表单上调用 ShowDialog:

//Static method on LockWaitForm
public static LockDetails Lock(string lockedMessage, object[] params parameters)

        using (LockWaitForm form = new LockWaitForm(parameters))
        
            form._lockedMessage.Text = lockedMessage;

            DialogResult result = form.ShowDialog();

            return new LockDetails (form._lockStatus, form._lock);
        
 

我想要的是对话框的 OnLoad 方法在显示之前等待 最多 秒,因此只有在 1 秒后无法锁定记录时才会显示。如果在 1 秒之前获得锁,它将在 1 秒之前退出,将其 DialogResult 设置为 OK。

所有功能都可以正常工作,除了对话框隐藏 1 秒。所有 'Visible = false' 调用都会被忽略,我可以理解他们为什么会这样做。这样做的问题是,每次使用表单时,错误的“记录已锁定”都会闪现不到一秒,并且可以毫无问题地获得锁定。

我可以想出一些技巧来延迟对话框的可见性

将不透明度设置为 0% - 这不适用于远程桌面连接 只有在 1 秒过后才通过静态方法初始化表单。这是有希望的,但需要大量重复的静态代码和非静态代码来处理锁的设置和处置,而且仍然感觉有点 hacky。

是否可以限制通过 ShowDialog 调用的 Modal Dialog 的显示?在这一点上,我很不情愿地 PInvoke(尽管我确实想限制非 64 位代码以满足未来的需求)

编辑

通过将获取锁定代码移动到窗体的构造函数而不是加载,我可以将锁定代码保留在一个位置,并在调用 ShowDialog 之前等待窗体的锁定状态处于等待状态。仍然感觉很脏,但迄今为止最干净的方法

【问题讨论】:

【参考方案1】:

我会重构应用程序,甚至不显示模式对话框,直到锁定过程未能实现锁定一秒钟。

【讨论】:

我得出的结论是,这可能是前进的方向,但正如我所说,在我的情况下确实需要一些重复的代码 您可以采纳MusiGenesis 的建议,通过覆盖ShowDialog() 将该逻辑封装在当前的LockWaitForm 中。这在架构上并不完全干净,但可能是一个好的、实用的解决方案。 @Eric,我同意,它很好地封装了逻辑,并且很大程度上对调用者隐藏【参考方案2】:

不确定这是否可行,但是:在您的 LockWaitForm 中,使用您自己的版本覆盖 ShowDialog(),该版本调用代码以获取锁(或任何它正在执行的操作),然后如果超过 1 秒,请调用它。 ShowDialog() (真实的)。这应该只允许您更改 LockWaitForm 中的代码,而不是其他任何地方。

抱歉,我的装有 Visual Studio 的笔记本电脑现在放在朋友的后备箱里,所以我无法检查这是否可行。

【讨论】:

很高兴工作。现在你可以让我的朋友接听他的电话吗?【参考方案3】:

什么样的锁?只是一个普通的线程锁?可以只使用 Monitor.TryEnter 吗?

如果它返回 false,则锁正忙,您可以弹出某种重试/取消锁等待窗口。

如果是真的,就照常生活吧。

作为一般性评论,我非常同意 Eric J 的观点,即在锁定失败之前您不应该显示表单。使用错误对话框执行普通的工作流,并试图在非错误情况下偷偷隐藏它似乎很尴尬。

相反,您应该有一个完全在错误对话框之外进行锁定的正确工作流,并且只在错误工作流上弹出对话框。

【讨论】:

不,锁是一个数据库记录,就像锁一样,是我们系统专有的(由于很多原因我不会在这里介绍) 这个锁定系统的 API 是什么?您是否调用 GetLock() 并永远阻塞?或者你是在循环中说 TryGetLock() 吗?在后一种情况下,很容易继续重试并计算重试所花费的总时间,然后在你点击一秒钟后弹出窗口。在前一种情况下,希望您可以定义某种超时,否则您将遇到更困难的线程问题。我认为,分享 lock-grab 调用的性质以获得更好的帮助。

以上是关于加载时显示 C# 延迟模式对话框,同时允许继续执行的主要内容,如果未能解决你的问题,请参考以下文章

C#打印图片设置报错 当应用程序不是以 UserInteractive 模式运行时显示模式对话框或窗体是无效操作。

单击按钮时显示 jquery 数据表模式对话框不起作用

如何在加载延迟加载的路由组件时显示“加载”动画?

首次加载时显示collectionView的底部,无需滚动和延迟加载

Android - 仅在 AsyncTask 未完成时单击按钮时显示进度对话框

页面加载时不需要的空模态