【问题标题】:Why would commenting out a line of code change whether a *previous* line of code is executed?为什么注释掉一行代码会改变 *previous* 行代码是否被执行?
【发布时间】:2013-06-07 03:34:44
【问题描述】:

使用此代码:

    using (pbDialog = new pbDialogs())
    {
        ProgressBar = new frmProgress(this, false);
        ProgressBar.SetProgressLabelText("Inventory Data");
        MessageBox.Show("Set progress label text to Inventory data");
        typeProgress = (int) ProgressStates.ProgressQRY;

        ProgressBar.label1.Text += " (Receiving)";
        if (pbDialog != null)
        {
            MessageBox.Show("pbDialog is not null");
            //pbDialog.ShowDialog(ProgressBar, this);
        }
        else
        {
            MessageBox.Show("pbDialog IS null");
            ProgressBar.ShowDialog();
        }

        ProgressBar = null;

        MessageBox.Show("Made it to compressDB()");
        compressDB();
        . . .
     }

我看到“将进度标签文本设置为库存数据” 那么“pbDialog 不为空” 然后“压缩DB()

那里没什么奇怪的;但是如果我取消注释上面注释的行,我只会看到“pbDialog is not null

由于对 ShowDialog() 的调用,它因某种原因挂起;不过,真正奇怪的是,这会阻止显示“将进度标签文本设置为库存数据”。为什么会这样?

注意:我认为代码中的“pb”代表“花生脆”之类的;无论如何,我很确定“脆弱”部分。

更新

是的,将 ShowDialog() 与 pbDialog 结合使用是原始编码员默默无闻地练习工作保障的众多示例之一 - 但后来他 [un] 幸运的是,在他身后留下了一堆意大利面条/蛋壳代码没有 cmets、误导性的名称以及在女巫酿造中可以想象到的各种奇怪、令人费解、违反直觉的做法,据称他认为这是优雅设计和巧妙技巧的杰作。

pbDialog 是一个类 (pbDialogs) 的实例。只是为了让您体验一下这一切是多么令人毛骨悚然、令人费解和纠缠不清,这是那堂课:

public class pbDialogs : IDisposable
{
    private static Form m_top;

    public pbDialogs()
    {
    } // pbDialogs Constructor


    public static void Activate( Form form )
    {
        form.Capture = true;
        IntPtr hwnd  = OpenNETCF.Win32.Win32Window.GetCapture();
        form.Capture = false;
        OpenNETCF.Win32.Win32Window.SetForegroundWindow( hwnd );
    } // Activate

    /// <summary>
    /// This method makes ShowDialog work the way I want, I think.
    /// </summary>
    /// <remarks>
    /// Here is what it does:
    ///   1.  Sets the caption of the new window to the same as the caller's.
    ///   2.  Clears the caption of the parent so it won't show up in the task list.
    ///   3.  When the ShowDialog call returns, brings the previous window
    ///       back to the foreground.
    /// </remarks>
    /// <param name="dialog"></param>
    /// <param name="parent"></param>
    public void ShowDialog( Form dialog, Control parent )
    {
        Control top    = parent.TopLevelControl;
        string caption = top.Text;
        dialog.Text    = caption;
        top.Text       = "--pending--";                 // Don't show parent in task list
        dialog.Activated += new EventHandler( form_Activated );
        dialog.Closed    += new EventHandler( form_Closed );
        m_top = dialog;                         // New top-most form
        dialog.ShowDialog();
        m_top = (Form)top;                      // The top dialog just changed
        dialog.Activated -= new EventHandler( form_Activated );
        dialog.Closed    -= new EventHandler( form_Closed );
        top.Text = caption;                     // Make visible in task list again
        Activate( (Form)top );                  // And make it the active window
    } // ShowDialog

    /// <summary>
    /// If one of our other windows, such as the main window, 
    /// receives an activate event, it will activate the current 
    /// top-most window instead.
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private static void form_Activated( object sender, EventArgs e )
    {
        if( (m_top != null) && !(sender == m_top) ) // Is this the top-most window?
            Activate( m_top );                      // No, activate the top dialog
    } // form_Activated

    private static void form_Closed( object sender, EventArgs e )
    {
        m_top = null;               // When you close the top dialog, it's not top anymore
    } // form_Closed

    #region IDisposable Members
    public void Dispose()
    {
        // TODO:  Add pbDialogs.Dispose implementation
    }
    #endregion
} // class pbDialogs

还有一个“相关的”ProgressBar——一种与 pbDialogs 共享文件的表单,其实例变量在包含上述代码的文件中定义:

public static frmProgress ProgressBar;

这绝对是“打地鼠”的代码 - 如果我做出一个看似无害的小改动,整个达拉斯都会崩溃,即使是半理智的人也会认为代码中完全不相关的部分。

这可能表明此代码/项目是多么松散:我将在注释掉几行后新建一个版本,文件大小将从 400KB 更改为 408,或从 412 更改为 408 ,等等。对于一个 .exe 来说,通过这么小的变化来改变这么大的大小(在相对意义上)是不正常的行为,是吗?

更新 2

这在 frmProgress(同时具有“public class frmProgress : System.Windows.Forms.Form”和“public class pbDialogs : IDisposable”)让我害怕:

using System.Windows.Forms;
using OpenNETCF.Windows.Forms;

第二个(OpenNETCF)是灰色的,表示它并没有真正使用,但可能是它以前被使用过,并且不知何故“Windows.Forms”代码无意中切换到了“System”代码,这可能是促成了它目前的古怪。

【问题讨论】:

  • 是Debug还是Release代码?
  • 似乎pbDialog 可能在代码继续之前等待某种输入。但奇怪的是它会阻止以前的MessageBox 显示......
  • pbDialog 到底是什么?标准的 Form.ShowDialog 没有那个签名(它可以只带一个参数,也可以不带)。
  • @Matt Seiker:我在上面以一种相当冗长、恼怒和刻薄的方式回答你的问题。
  • @Evan:这段代码在过去是有效的(尽管它很不稳定,就像一个蹒跚学步的字母积木塔)。

标签: c# .net-1.1


【解决方案1】:

ShowDialog 通常是阻塞调用。在对话框关闭之前,代码不会继续运行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-20
    • 2017-02-28
    • 1970-01-01
    • 2012-05-26
    • 1970-01-01
    • 2021-01-08
    • 2023-01-23
    • 1970-01-01
    相关资源
    最近更新 更多