C#의 Winform에서 Form을 생성해보면

*.cs와 *.Designer.cs가 생성됩니다.

 

partial Class로써 디자인 부분과 개발 코드가 분리 되어 있습니다.

 

디자인의 초기화 하는 메서드를 확인해보면 아래와 같이

붉은 부분의 코드가 작성되어 있는것을 확인 하실 수 있습니다.

 

        /// <summary>
        /// 디자이너 지원에 필요한 메서드입니다.
        /// 이 메서드의 내용을 코드 편집기로 수정하지 마십시오.
        /// </summary>
        private void InitializeComponent()
        {
            this.SuspendLayout();
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(678, 416);
            this.Name = "Form1";
            this.Text = "Form1";
            this.Load += new System.EventHandler(this.Form1_Load);
            this.ResumeLayout(false);

        }


 

 

SuspendLayout과 ResumeLayout이 뭔지 살펴보겠습니다.

둘다 Control Class의 메서드로써 MSDN을 살펴보면 아래와 같습니다.

 

 

 SuspendLayout 메서드는 컨트롤의 Layout 논리를 임시로 일시 중단합니다.

ResumeLayout 메서드는 일반 레이아웃 논리를 다시 시작합니다.

 

 

 ResumeLayout 메서드가 호출될 때까지 컨트롤의 레이아웃 논리가 일시 중단됩니다.

SuspendLayout ResumeLayout 메서드는 차례로 사용되어 컨트롤의 여러 특성을 조정하는 동안 여러 Layout 이벤트가 발생하지 않도록 합니다.

예를 들어 SuspendLayout 메서드를 호출하고 컨트롤의 Size, Location, Anchor 또는 Dock 속성을 설정한 다음 ResumeLayout 메서드를 호출하면 변경 사항이 적용됩니다.

ResumeLayout 을 성공적으로 호출하려면 SuspendLayout에 대해 보류 중인 호출이 없어야 합니다.

 

주목! 

 하나의 부모 컨트롤에 여러 개의 컨트롤을 추가할 경우 추가할 컨트롤을 초기화하기 전에 SuspendLayout 메서드를 호출하는 것이 좋습니다.

부모 컨트롤에 컨트롤을 추가한 후 ResumeLayout 메서드를 호출합니다.이렇게 하면 컨트롤이 많은 응용 프로그램의 성능이 향상됩니다.

 

 SuspendLayout MSDN 바로가기

ResumeLayout MSDN 바로가기

 

 

 

아래의 코드로 테스트를 진행해 보았습니다.

 

 

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace TestLayoutPerformance
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch();

            
            int testCount = 10;
            
            stopWatch.Start();
            this.UseLayout(testCount);
            stopWatch.Stop();
            System.Diagnostics.Debug.WriteLine(string.Format("Not raised layout event time:{0}",stopWatch.Elapsed.ToString()));

            this.Controls.Clear();


            stopWatch.Restart();

   this.NotUseLayout(testCount); stopWatch.Stop(); System.Diagnostics.Debug.WriteLine(string.Format("Raised layout event time:{0}", stopWatch.Elapsed.ToString())); } /// <summary> /// Layout 이벤트를 발생시키지 않습니다. /// </summary> /// <param name="testCount"></param> private void NotUseLayout(int testCount) { Random rand = new Random(); for (int i = 0; i < testCount; i++) { Button btn = new Button(); btn.Text = i.ToString(); btn.Location = new Point(rand.Next(0, this.Width), rand.Next(0, this.Height)); this.Controls.Add(btn); } } /// <summary> /// Layout 이벤트를 발생시킵니다. /// </summary> /// <param name="testCount"></param> private void UseLayout(int testCount) { Random rand = new Random(); this.SuspendLayout(); for (int i = 0; i < testCount; i++) { Button btn = new Button(); btn.Text = i.ToString(); btn.Location = new Point(rand.Next(0, this.Width), rand.Next(0, this.Height)); this.Controls.Add(btn); } this.ResumeLayout(false); } } }

 

 

 

 

테스트 결과를 확인해보면..

많은 개수의 Control 개체를 추가할때 속도 개선에 도움을 줍니다..

(SuspendLayout 메서드를 호출하게되면 Layout 이벤트는 발생하지 않으므로..)

 

500개 Control 생성시 결과:
Not raised layout event time:00:00:00.0212146
Raised layout event time:00:00:00.0286526

 

1000개 Control 생성시 결과:
Not raised layout event time:00:00:00.0736165

Raised layout event time:00:00:00.1003722

 

5000개 Control 생성시 결과:
Not raised layout event time:00:00:01.6119380

Raised layout event time:00:00:02.3460958

 

 

10000개 Control 생성시 결과:
Not raised layout event time:00:00:06.6405698

Raised layout event time:00:00:09.6261999



 

 

 

 

 

TestLayoutPerformance.zip

+ Recent posts