【问题标题】:Launching Winform App Using Static Form Variable使用静态表单变量启动 Winform 应用程序
【发布时间】:2013-03-29 15:48:01
【问题描述】:

我想知道使用程序级静态表单变量来保存对我的 MainUI 表单的引用是否是一种安全的技术,或者我是否引入了可能导致线程或其他问题的东西?具体来说,我担心从应用程序中的多个位置调用静态变量的实例方法。只要对这些实例方法的所有调用都发生在应用程序线程中,我就安全了吗?

static class Program
{
    static internal MainUI MainUI;

    [STAThread]
    static void Main()
    {
        ...            
        AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
        Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
        MainUI = new MainUI();
        Application.Run(MainUI);
        ...    
    }

    static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
    {
        ...
        MainUI.SetBusyState(false);
        ...
    }

    static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        ...
        MainUI.SetBusyState(false);
        ...
    }

上面的代码完成了几件事。

首先,应用程序本身有数百个不同的调用来通过互联网检索数据,这通常需要几秒钟才能完成。在此期间,需要禁用 MainUI 并显示等待光标。我可以依赖 Application_ThreadException 和 CurrentDomain_UnhandledException 处理程序,而不是将每个调用都包装在 try catch 块中,以便在发生异常时正确重置 MainUI 的状态,在这些处理程序中,我可以使用 MainUI.SetBusyState 方法重新启用 UI。

其次,我可以在 MainUI 上创建有用的实例方法,并使用 Program.MainUI 以干净的方式将它们提供给应用程序的其余部分。例如,我可以在我的用户控件中使用 Program.MainUI.SetBusyState 而不是 ((MainUI)this.ParentForm).SetBusyState。但是使用这样的实例方法是我主要关心的问题。

谢谢!

【问题讨论】:

    标签: c# winforms static


    【解决方案1】:

    您在那里所做的事情非常合法,因为应用程序本身只有一个主窗体,只有在应用程序关闭时才会被销毁。如果您使用其他形式执行此操作,那将是一个更大的问题。

    但是,如果你想摆脱静态变量,你可以这样做:

       [STAThread]
       static void Main()
       { 
            MainUI form = new MainUI();
            AppDomain.CurrentDomain.UnhandledException += (s,e)=> {
                form.SetBusyState(false);
            };
            Application.ThreadException += (s,e)=> {
                form.SetBusyState(false);
            };  
            Application.Run(form);
        }
    

    【讨论】:

    • 不,你不能那样做。 Application.ThreadException 很特殊,它只能有 一个 事件处理程序。你用完了唯一的。试试看。
    • @HansPassant 所以如果这是唯一使用它的地方有什么问题? OP 已经以同样的方式使用它
    • 嗯,你没试过。它不是唯一使用它的地方。
    • @HansPassant 你是说我的代码也不可能,还是只是 Sten 的提议?
    • @HansPassant 你要告诉我们什么在这里不起作用吗?重点是如何设置主窗体的忙碌状态,而不是记录。为了完整起见,我们是否还要在这里编写整个应用程序?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-01
    • 2021-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多