Windows窗体:由应用程序而不是用户打开/关闭的模式窗体?

时间:2008-10-01 15:11:36

标签: .net winforms multithreading

我有一个相信结构良好的.NET 3.5表单应用程序(单元测试,依赖注入,SoC,表单只是中继输入和显示输出,不做任何逻辑,yadda yadda)我只是错过了关于如何让这一点工作的winforms知识。

当与数据库的连接丢失时 - 经常发生 - 我正在检测并处理它,并希望弹出一个模态表单,阻止使用应用程序直到重新建立连接。我不是百分百肯定如何做到这一点,因为我不是在等待用户输入,而是我使用计时器轮询数据库。

我的尝试是设计一个带有标签的表格并执行此操作:

partial class MySustainedDialog : Form {
    public MySustainedDialog(string msg) {
        InitializeComponent();
        lbMessage.Text = msg;
    }
    public new void Show() {
        base.ShowDialog();
    }

    public new void Hide() {
        this.Close();
    }

}

public class MyNoConnectionDialog : INoConnectionDialog {
            private FakeSustainedDialog _dialog;
    public void Show() {
        var w = new BackgroundWorker();
        w.DoWork += delegate {
            _dialog = new MySustainedDialog("Connection Lost");
            _dialog.Show();
        };
        w.RunWorkerAsync();
    }

    public void Hide() {
        _dialog.Close();
    }
}

这不起作用,因为_dialog.Close()是一个跨线程调用。我已经能够找到有关如何在Windows窗体中解决此问题的信息,但不是在需要自己创建表单的情况下。

有人可以给我一些建议,告诉我如何实现我的目标吗?

编辑:请注意,我只是因为缺乏其他想法而尝试了背景工作者,因为我不太熟悉UI的线程如何工作,所以我完全乐于接受建议。我还应该注意到,我不想关闭他们当前正在处理的表单,我只是想让它出现在它上面。就像一个OK / Cancel对话框但我可以通过编程方式打开和关闭(我需要控制它的外观)

4 个答案:

答案 0 :(得分:2)

我不确定您整体方法的正确性,但要专门回答您的问题,请尝试将MySustainedDialog Hide()函数更改为:

    public new void Hide()
    {
        if (this.InvokeRequired)
        {
            this.BeginInvoke((MethodInvoker)delegate { this.Hide(); });
            return;
        }

        this.Close();
    }

答案 1 :(得分:1)

没有理由使用后台工作程序来实际启动表单的新实例,只需从UI线程中执行即可。

答案 2 :(得分:1)

我在类似的情况下采取了两种方法。

一种是完全在主UI线程中操作。您可以使用 Windows.Forms.Timer 实例执行此操作,该实例将在主UI线程中触发。

优点是对所有UI组件的简单性和完全访问权限。缺点是任何阻止呼叫都会对用户体验产生巨大影响,从而阻止任何用户交互。因此,如果您需要长时间运行的命令,最终导致UI操作(例如,如果检查数据库需要几秒钟),那么您需要进行跨线程。

从代码角度来看,最简单的跨线程解决方案是从BackgroundWorker中调用 Control.Invoke 方法。

Invoke允许你将工作“发布”到控件,实质上是说“请使用你自己的线程来运行它。”

答案 3 :(得分:0)

将所有UI工作保留在主UI线程上而不是使用BackgroundWorker可能更简单吗?如果没有看到更多的代码,说这很棘手,但我认为你不应该需要它。

创建计时器时,可以指定它的Timer.SynchronizingObject以使其使用主UI线程。并坚持下去?

抱歉,如果不了解有关程序结构的更多信息,则无法提供更好的答案。