작성
·
93
0
안녕하세요. 강의를 중반 쯤 듣고 강의한 내용 정리할겸 해서 새로운 프로젝트를 생성해서 테스트 진행 중입니다.
분명 강의 따라하면서 코딩을 할땐 잘 되었는데 제가 프로젝트를 만들어서 시작 하면 아래처럼 에러가 나오네요
일단 제가 작성한 코드를 알려드리면 아래와 같습니다.
===================================
namespace TestThread
{
public partial class Form1 : Form
{
Thread thread1 = null;
Thread thread2 = null;
public Form1()
{
InitializeComponent();
}
delegate void MySettingDelegate(string str);
private void btnThread_Click(object sender, EventArgs e)
{
thread1 = new Thread(new ThreadStart(ThreadFirst));
thread1.IsBackground = true;
thread1.Priority = ThreadPriority.Normal;
thread1.Start();
thread2 = new Thread(new ThreadStart(ThreadSec));
thread2.IsBackground = true;
thread2.Priority = ThreadPriority.Normal;
thread2.Start();
}
private void ThreadFirst()
{
MessageBox.Show("Thread1");
}
private void ThreadSec()
{
MessageBox.Show("Thread2");
}
private void Form1_Load(object sender, EventArgs e)
{
MySettingDelegate mySettingDelegate = MySetting;
mySettingDelegate.BeginInvoke("aaa", null, null);
}
private void MySetting(string str)
{
label1.Text = str; // ----- 여기서 문제
}
}
}
=======================================
좀 이해가 되는데 호출한 쓰레드에 작성된 label1 컨트롤에 새롭게 생성된 쓰레드에서 찾으려니 없는게 당연할듯 한데 ...
지금까지 강의을 따라하면서 저런 에러는 본적이 없거든요....
분명 같은 코드인데 다른 코드를 생성하고 있나 하고 코드를 비교 해봐도 다를껀 없는데 ...
추가 이미지 입니다.
답변 2
0
안녕하세요.개발자park입니다.
18:38에도 나옵니다.
main Thread(또는 UI-Thread로 불리는)가 호출하는 main method에서
컨트롤에 접근시 문제가 없습니다.
그러나 이외의 Thread에서 컨트롤(예를 들면 말씀하신 label)에 접근시
동일한 5강의 19:16에서와 같은 코드를 적어주셔야 됩니다.
감사합니다.
0
안녕하세요, 인프런 AI 인턴입니다. just kim님.
크로스 스레드 작업 문제로 인해 발생하는 System.InvalidOperationException
예외에 대한 질문을 주셨습니다. 이 문제는 주로 UI 요소가 생성된 스레드가 아닌 다른 스레드에서 접근할 때 발생합니다. 특히 다중 스레드를 사용할 때 흔히 발생하는 문제입니다.
아래 링크는 다중 스레드에서 UI 요소를 안전하게 조작하는 방법에 관련된 기존 질문과 답변입니다. 이를 참고하시면 도움이 될 것입니다.
UI 요소는 원래의 UI 스레드에서만 접근 및 수정할 수 있습니다. 이를 해결하기 위해서는 Invoke
또는 BeginInvoke
메서드를 사용하여 해당 작업을 UI 스레드에서 실행해야 합니다:
private void MySetting(string str)
{
if (label1.InvokeRequired)
{
label1.Invoke(new Action(() => MySetting(str)));
}
else
{
label1.Text = str;
}
}
위 코드처럼 InvokeRequired
속성을 사용하여 현재 스레드가 UI 스레드인지 확인하고, 만약 아닌 경우 Invoke
를 사용하여 UI 스레드에서 실행되도록 합니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.
또는 22:06코드로도 가능하겠습니다.
근본적으로 BeginInvoke로 호출해서 그렇습니다.
BeginInvoke:이는 ThreadPool에서 이미 생성되어있는 Thread를 가져와서 코드를 실행시킵니다.
감사합니다.