2008-10-08 6 views
1

기본적으로 사용자에게 대기 창을 표시해야합니다. 이를 위해 응용 프로그램에 두 개의 별도 윈도우 폼을 넣었습니다. 첫 번째 양식은 버튼이있는 기본 양식입니다. 두 번째 것은 레이블 텍스트가있는 빈 텍스트입니다. Form1의 버튼을 클릭하면 아래와 같이 나타납니다.Windows 응용 프로그램에서 창 대기

Form2 f = new Form2(); 
f.Show(); 
Thread.Sleep(2000); 
f.Close(); 

제 아이디어는 사용자에게 대기 시간을 2 초 동안 표시하는 것입니다. 그러나 내가 이것을 할 때 양식 2가 완전히로드되지 않아 그 안에 레이블이 비어 있습니다. 이것에 대한 귀하의 의견을 알려주십시오.

답변

3

같은 스레드 (UI 스레드)에서 오랜 시간 작업을 수행했기 때문입니다. 새로운 스레드 (코드는 Thread 클래스 참조)에서 코드를 실행하거나 긴 작업 내에서 주기적으로 Application.DoEvents를 호출하여 UI를 업데이트해야합니다.

+0

내가 Thread.sleep를 호출 넘어 길이 작업의 징후를 볼 :

여기
using WaitingBox; ShowWaitingBox waiting = new ShowWaitingBox("Title Text","Some Text so the user knows whats going on.."); waiting.Start(); //do something that takes a while waiting.Stop(); 

는 WaitingBox 코드입니다. 지연은 다른 스레드보다 Timer에서 더 잘 처리됩니다. 새 스레드를 시작하거나 Application.DoEvents를 사용할 필요가 없습니다. –

+0

Thread.Sleep은 실제 코드에 대한 자리 표시 자임을 이해합니다. –

+0

그것은 명확하지 않다 - 질문은 사용자에게 "대기 창"을 보여주는 것에 대해 이야기한다. OP가 진정으로 다른 작업을 원한다면 스레드 (및 BackgroundWorker)가 적합합니다. 그러나 여기에있는 경우에는 아무런 표시가 없습니다. –

1

기본적으로 UI 스레드를 차단하고 있습니다.

대신에 Form2 생성자 (또는 Load 이벤트 핸들러)가 2 초 후에 실행되는 타이머를 시작하도록 제안합니다. 타이머가 시작되면 양식을 닫습니다. 이 2 초 동안 UI 스레드는 무료이므로 모든 것이 올바르게 표시되고 사용자는 창 등을 이동할 수 있습니다.

2

언제 Thread.Sleep을 사용하면 Windows 메시지 루프를 비활성화하고 창을 막을 수 있습니다 그림 그 자체에서.

당신은 다시 그리기를 강제 수 :

f.Refresh(); 

또는 더 나은 아직 콜백와 타이머를 사용합니다.

f.ShowDialog(); 
-1

당신은 (AN 항상 UI 스레드가해야 용) Thread.Current.Join(2000)를 사용하는 대신에 Thread.sleep 수 있습니다

Timer t = new Timer(); 
t.Interval = 2000; 
t.Tick += delegate { Close(); t.Stop();}; 
t.Start(); 

는 대화로 새 양식을 열 수 있습니다 원래 창에 클릭하지 못하도록하려면 (2000).

+0

현재 스레드에서 호출 조인은이 문제를 해결하는 아주 이상한 방법입니다 (IMO). 타이머를 설정하고 작동 할 때 작업을 계속할 수 있도록 디자인하는 것이 훨씬 좋습니다. Re-entrancy is nasty : ( –

+0

) Join()을 사용할 때 재 입력이 필요하지 않습니다. (STA COM 객체 내에서 Join()을하고 다른 스레드가 호출하지 않는 한) 폼을 사용할 때 폼이 업데이트되지 않으므로 Join() 내부 구조체. –

0

나는 그냥 f를 닫을 때 반환되는 제어 그리고

f.ShowDialog(this); 

를 사용한다고 생각합니다.

잠을 사용하면 UI 스레드가 2 초 동안 업데이트되지 않습니다. (스레드가 잠 들어 있습니다).

3

다음은 내가 사용하는 대기실 클래스입니다. 여기 당신이 그것을 사용하는 방법입니다

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



    namespace WaitingBox 
    { 
      public class ShowWaitingBox 
      { 
        private class WaitingForm:Form 
        { 
          public WaitingForm() 
          { 
            this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); 
            this.label1 = new System.Windows.Forms.Label(); 
            this.progressBar1 = new System.Windows.Forms.ProgressBar(); 
            this.tableLayoutPanel1.SuspendLayout(); 
            this.SuspendLayout(); 
            // 
            // tableLayoutPanel1 
            // 
            this.tableLayoutPanel1.ColumnCount = 1; 
            this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); 
            this.tableLayoutPanel1.Controls.Add(this.progressBar1, 0, 0); 
            this.tableLayoutPanel1.Controls.Add(this.label1, 0, 2); 
            this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; 
            this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0); 
            this.tableLayoutPanel1.Name = "tableLayoutPanel1"; 
            this.tableLayoutPanel1.RowCount = 3; 
            this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); 
            this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 29F)); 
            this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); 
            this.tableLayoutPanel1.Size = new System.Drawing.Size(492, 155); 
            this.tableLayoutPanel1.TabIndex = 0; 
            // 
            // label1 
            // 
            this.label1.Anchor = System.Windows.Forms.AnchorStyles.Top; 
            this.label1.AutoSize = true; 
            this.label1.Location = new System.Drawing.Point(209, 92); 
            this.label1.Name = "label1"; 
            this.label1.Size = new System.Drawing.Size(73, 13); 
            this.label1.TabIndex = 3; 
            this.label1.Text = "Please Wait..."; 
            // 
            // progressBar1 
            // 
            this.progressBar1.Anchor = System.Windows.Forms.AnchorStyles.Bottom; 
            this.progressBar1.Location = new System.Drawing.Point(22, 37); 
            this.progressBar1.Name = "progressBar1"; 
            this.progressBar1.Size = new System.Drawing.Size(447, 23); 
            this.progressBar1.TabIndex = 2; 
            // 
            // WaitingForm 
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 
            this.ClientSize = new System.Drawing.Size(492, 155); 
            this.Controls.Add(this.tableLayoutPanel1); 
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; 
            this.Name = "WaitingForm"; 
            this.Text = "Working in the background"; 
            this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.WaitingForm_FormClosing); 
            this.Load += new System.EventHandler(this.WaitingForm_Load); 
            this.tableLayoutPanel1.ResumeLayout(false); 
            this.tableLayoutPanel1.PerformLayout(); 
            this.ResumeLayout(false); 
          } 

          private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; 
          private System.Windows.Forms.ProgressBar progressBar1; 
          private System.Windows.Forms.Label label1; 

          private void WaitingForm_Load(object sender, EventArgs e) 
          { 
            progressBar1.Style = ProgressBarStyle.Marquee; 
            this.BringToFront(); 
            this.CenterToScreen(); 
          } 

          private void WaitingForm_FormClosing(object sender, FormClosingEventArgs e) 
          { 
          } 

          internal void SetLabel(string p) 
          { 
            label1.Text = p; 
          } 
        } 
        private WaitingForm wf = new WaitingForm(); 
        private string title, text; 
        private Thread waiting; 
        public bool IsAlive 
        { 
          get 
          { 
            return waiting.IsAlive; 
          } 
          set { } 
        } 
        public ShowWaitingBox(string Title, string Text) 
        { 
          this.title = string.IsNullOrEmpty(Title) ? "Working in the Background..": Title; 
          this.text = string.IsNullOrEmpty(Text) ? "Please wait..." : Text; 
          waiting = new Thread(new ThreadStart(Show)); 

        } 

        public ShowWaitingBox() 
        { 
          waiting = new Thread(new ThreadStart(Show)); 
        } 

        private void Show() 
        { 
          wf.Show(); 
          wf.Text = this.title; 
          wf.SetLabel(this.text); 
          while (true) { 

            wf.Refresh(); 
            System.Threading.Thread.Sleep(50); 
          } 
        } 
        public void Start() 
        { 
          waiting.Start(); 
        } 
        public void Stop() 
        { 
          waiting.Abort(); 
        } 
      } 
    } 
관련 문제