2014-09-11 1 views
0

예를 들어 Windows Form에는 2 개의 명령 단추와 텍스트 상자가 있습니다. 명령 단추 1을 클릭에
이 텍스트 상자 값은 1에서 1000000코드 실행 중 Windows Forms에 액세스 할 수 없음

이런 일이 발생하는 동안 말할 증가 계속, 나는 명령 단추 2.
내가 할 수있는 포함, 양식에 아무 곳이나 클릭 할 수 없습니다입니다 카운터가 1000000에 멈춘 경우에만 양식에 다시 액세스하십시오.

이 문제에 대해 조언하십시오.

또한 *.Show(); 방법을 사용하여 모덜리스 형식을 사용해 보았습니다.

이것은 TextBox에서 값을 가져 오는 코드입니다.

for (int i = 0; i <= 10000; i++) 
{ 
    Console.WriteLine(i); 
    this.textBox1.Text = Convert.ToString(i); 

    label2.Focus(); 
    this.textBox1.Focus(); 
} 
+5

UI에서 코드를 모두 실행하고 있기 때문에 디스플레이 업데이트를 처리 할 수 ​​없기 때문입니다. –

+1

응용 프로그램은 메시지를 펌핑 할 때만 응답합니다. 코드의 중간에 루프가 돌아가는 중일 때 메시지를 펌프로 보낼 수 없습니다 (그렇지 않으면!) –

+0

코드가 UI 스레드에서 실행 중이면 애플리케이션이 실행될 때까지 차단됩니다. 코드가 실행을 마쳤습니다. 이것을 별도의 스레드에서 실행하기위한'Task' 클래스를보십시오. http://msdn.microsoft.com/en-us/library/system.threading.tasks.task(v=vs.110).aspx –

답변

0

왜냐하면 이벤트를 발생시키고 싶은 동일한 스레드 (즉, 클릭 버튼)에서 완료하는 데 시간이 걸리는 작업을 수행하기 때문입니다. 단일 스레드에서 모든 작업은 한 번에 하나씩 일련의 방식으로 수행됩니다. 즉, 한 작업이 완료되면 다른 작업이 시작됩니다.

이렇게하려면이 작업을 주 스레드가 아닌 다른 스레드에서 실행해야합니다. 이 DotNet Perls Link 이 당신을 돕기를 바랍니다.

0

다른 스레드에서 UI와 상호 작용하려면 대리자를 사용하고 Control.Invoke/BeginInvoke을 호출하여 UI 스레드에 대한 호출을 "마샬링"해야합니다.

textBox1.Invoke((MethodInvoker)(() => textBox1.Text = Convert.ToString(i))); 

모든 브래킷이 방법으로 비트를 얻을, 그래서 당신은 C# 3.0을 사용하는 경우는, 다음과 같이 확장 메서드를 추가 할 수 있습니다 :

예를 들어, 당신은 사용할 수

public static void Invoke(this Control control, MethodInvoker action) 
{ 
    control.Invoke(action); 
} 

그런 다음 당신은 할 수 :

textBox1.Invoke(() => textBox1.Text = Convert.ToString(i)); 
0

윈도우의 주요 ("사용자 인터페이스") 스레드가 APPLIC 양식 ation은 기본적으로 큐에서 메시지를 처리하는 무한 루프입니다. 사용자가 마우스를 움직이거나 마우스를 클릭하거나 키를 누를 때 OS는 어떤 응용 프로그램이 해당 입력을 처리해야하는지 결정하고 해당 응용 프로그램의 대기열에 메시지를 추가합니다. 메시지 대기열에 메시지가 있음을 알 때 응용 프로그램은 메시지를 처리합니다. 예를 들어 Windows Forms 컨트롤에서 클릭이 발생하면 사용자 코드에서 처리되는 Click 이벤트가 발생합니다.

여기에 코드가 들어 있습니다. 예를 들어, UI를 업데이트하는 긴 루프를 통해 실행되는 첫 번째 명령 단추에 대한 클릭 핸들러를 작성합니다. 코드가 실행되는 동안 대기열의 다른 메시지는 처리되지 않습니다. 이는 명령 단추 2와 같은 다른 컨트롤에 대한 클릭이 처리되고 있지 않음을 의미합니다. Click 처리기가 반환 한 후에 만 ​​메시지 루프가 이벤트 처리를 계속합니다.

UI를 응답 성있게 유지하려면 짧은 간격으로 설정된 System.Windows.Forms.Timer를 사용하고 루프에서 한 반복 작업을 수행하여 Tick 메서드를 처리 할 수 ​​있습니다. 그렇게하면 틱마다 UI 스레드를 간단히 묶을 수 있고 틱간에 다른 이벤트를 처리 할 수 ​​있습니다.

또는 백그라운드 스레드에 대한 작업을 배울 수도 있지만 클릭 처리기의 대부분이 UI를 업데이트하는 것이 최선의 해결책은 아닐 수도 있습니다. 백그라운드 스레드에서 UI를 업데이트하는 것은 합법적이지 않습니다. UI를 업데이트하는 메서드는 Kai에서 설명한대로 Control.Invoke 또는 Control.BeginInvoke을 사용하여 UI 스레드에서 실행해야합니다.

관련 문제