다른 스레드에서 WinForms 개체에서 form.show()
를 호출하면 양식에서 예외가 발생합니다. 메인 앱 스레드에 표시되는 새 양식을 추가할 수 있는 방법이 있나요? 그렇지 않으면 현재 실행 중인 스레드를 중지하지 않고 양식을 열려면 어떻게 해야 하나요?
다음은 제 샘플 코드입니다. 스레드를 시작한 다음 해당 스레드 내에서 일부 작업을 실행하려고 합니다. 작업이 진행됨에 따라 양식을 표시합니다.
public void Main()
{
new Thread(new ThreadStart(showForm)).Start();
// Rest of main thread goes here...
}
public void showForm()
{
// Do some work here.
myForm form = new myForm();
form.Text = "my text";
form.Show();
// Do some more work here
}
호출 호출을 사용해 보세요:
public static Form globalForm;
void Main()
{
globalForm = new Form();
globalForm.Show();
globalForm.Hide();
// Spawn threads here
}
void ThreadProc()
{
myForm form = new myForm();
globalForm.Invoke((MethodInvoker)delegate() {
form.Text = "my text";
form.Show();
});
}
호출 호출은 양식에 "이 코드를 내 스레드가 아닌 귀하의 스레드에서 실행하십시오."라고 알려줍니다. 그러면 델리게이트 내에서 WinForms UI를 변경할 수 있습니다.
호출에 대한 자세한 문서는 여기를 참조하세요: http://msdn.microsoft.com/en-us/library/zyzhdc6b.aspx
편집: 호출을 호출하려면 이미 존재하는 WinForms 개체를 사용해야 합니다. 여기에서는 전역 객체를 만드는 방법을 보여드렸지만, 다른 윈도우 객체가 있는 경우 해당 객체도 작동합니다.
form.Show()를 호출한 후
Application.Run()`을 호출해야 합니다. 예를 들어
public void showForm()
{
// Do some work here.
myForm form = new myForm();
form.Text = "my text";
form.Show();
Application.Run();
// Do some more work here
}
그 이유에 대한 자세한 내용은 이 msdn 게시물이 도움이 될 수 있습니다.
제 경험상 가장 좋은 방법입니다:
var ac = (ReportPre)Application.OpenForms["ReportPre"];
Thread shower = new Thread(new ThreadStart(() =>
{
if (ac == null)
{
this.Invoke((MethodInvoker)delegate () {
ac = new ReportPre();
ac.Show();
});
}
else
{
this.Invoke((MethodInvoker)delegate
{
pictureBox1.Visible = true;
});
if (ac.InvokeRequired)
{
ac.Invoke(new MethodInvoker(delegate {
ac.Hide();
ac.Show();
}));
}
}
}));
shower.Start();