2010-12-15 2 views
4

C#을 처음 접한다면 나와 함께 맨손으로. 다른 클래스를 실행하는 새 스레드에서 주 스레드의 텍스트 상자 및 레이블을 업데이트하는 방법주 스레드의 텍스트 상자를 다른 스레드에서 업데이트하는 방법은 무엇입니까?

MainForm.cs (메인 스레드)

public partial class MainForm : Form 
{ 
    public MainForm() 
    { 
     Test t = new Test(); 

     Thread testThread = new Thread(new ThreadStart(t.HelloWorld)); 
     testThread.IsBackground = true; 
     testThread.Start(); 
    } 

    private void UpdateTextBox(string text) 
    { 
     textBox1.AppendText(text + "\r\n"); 
    } 

} 

public class Test 
{ 
    public void HelloWorld() 
    { 
     MainForm.UpdateTextBox("Hello World"); 
     // How do I execute this on the main thread ??? 
    } 
} 

내가 여기에있는 예제를 보았다하지만 캔트 바로 그것을 얻을 것으로 보인다. 누군가 좋은 링크를 줄 수 있습니까?

나는 코드를 엉망으로 만들지 않으므로 다시 시작했습니다. 누구든지 위대한 일이 될만한 모범을 보여주고 싶다면.

또한 텍스트 상자 및 레이블 등 (동시에 모두는 아님)과 같은 여러 개체를 업데이트해야하는 경우 각 텍스트 상자에 대해 메서드를 사용하는 것이 가장 좋은 방법 일 것이거나이를 수행 할 수있는 방법이 있습니다. 하나의 방법으로? 내가 새로운 사람이라고 말했듯이 천천히 말하십시오.

+0

환영을 사용하는 것입니다 : 당신은 람다 표현식에 읽을 수있는과 함께 편안하고 좋아합니까

public class MainForm : Form { public MainForm() { Test t = new Test(); Thread testThread = new Thread((ThreadStart)delegate { t.HelloWorld(this); }); testThread.IsBackground = true; testThread.Start(); } public void UpdateTextBox(string text) { Invoke((MethodInvoker)delegate { textBox1.AppendText(text + "\r\n"); }); } } public class Test { public void HelloWorld(MainForm form) { form.UpdateTextBox("Hello World"); } } 

그래서. 질문을 편집하여 추가 정보를 추가 할 수 있으며 질문 한 사항에 대한 답변 (그리고 50 명을 기록한 후에는 아무 것도)을 남길 수 있습니다. – Will

답변

3

BeginInvoke method을 호출하면 대리인이 UI 스레드에서 비동기 적으로 실행될 수 있습니다.

UI 스레드에서 함수가 완료 될 때까지 백그라운드 스레드가 대기해야하는 경우 Invoke을 대신 호출 할 수 있습니다.

양식 인스턴스에 대한 참조가 필요합니다. 당신은 아마도 Test 생성자에 그것을 전달하고 그것을 private 필드에 저장해야합니다.


BackgroundWorker component 자동으로 ReportProgress 방법을 사용하여이 모든 것을 할 것입니다; 당신은 그것을 사용하는 것을 고려해야합니다.

+0

대답 주셔서 감사하지만, C#에 익숙하지 않으므로 어떻게 작동하는지 이해할 수 있도록 예제를 제시해야합니다. – tiptopjones

+1

@tiptop : 그런 다음 BackgroundWorker를 사용해야합니다. [MSDN 예제가 있습니다] (http://msdn.microsoft.com/en-us/library/waw3xexc.aspx) – SLaks

+0

모든 WinForms 개발자는 threadsafe 방식으로 UI를 업데이트하는 방법을 이해해야하며 두 방법 모두 – STW

6

Invoke 또는 BeginInvoke.

Invoke((MethodInvoker)delegate { 
    MainForm.UpdateTextBox("Hello World"); 
}); 

@tiptopjones 나는 양식에 대한 참조를 가져 오는 방법도 요구하고 같아요. HelloWorld 메서드가 개체 매개 변수를 사용하도록 만들고 ParameterizedThreadStart 대리자를 사용하고 폼에 대한 참조를 Thread.Start 메서드의 매개 변수로 전달할 수 있습니다. 그러나 나는 익명의 방법에 대해 읽는 것이 좋을 것이다. 익명의 방법은 훨씬 쉽게 만들고 모든 것을 강력하게 입력한다.

Thread testThread = new Thread(() => t.HelloWorld(this)); 
+0

안녕하세요. 질문을 편집하여 다른 답변을 제공하는 것보다 더 많은 정보를 추가하는 것이 바람직합니다. – Will

1

윈폼의 선호하는 방법에 SynchronizationContext에이

public partial class MainForm : Form 
{ 
    SynchronizationContext ctx; 

    public MainForm() 
    { 
     ctx = SynchronizationContext.Current; 

     Test t = new Test(); 

     Thread testThread = new Thread(new ThreadStart(t.HelloWorld)); 
     testThread.IsBackground = true; 
     testThread.Start(); 
    } 

    private void UpdateTextBox(string text) 
    { 
     ctx.Send(delegate(object state) 
     { 
      textBox1.AppendText(text + "\r\n"); 

     },null); 
    }  
} 

public class Test 
{ 
    public void HelloWorld() 
    { 
     MainForm.UpdateTextBox("Hello World"); 
     // How do I excute this on the main thread ??? 
    } 
} 
관련 문제