거기에는 비슷한 질문이 많이 있고 그 중 많은 부분을 읽었습니다. 불행히도, 나는 그들을 통해 읽은 후에도 여전히 내 문제를 해결할 수 없다 - 그러나 나는 C#에 비교적 익숙하지 않다. docs에 따르면 스레드 안전하지 않은 문제는 디버거를 사용할 때 InvalidOperationException
이됩니다. 이것은 내 문제의 경우가 아닙니다.다른 양식으로 대화 상자 업데이트하기
간단한 생생한 테스트 클래스로 문제를 재 작성하여 내 문제에 집중했습니다.
기본 양식은 일종의 진행 대화 상자를 표시합니다. 그 코드는 기본 폼에서 모든 호출()없이 호출
public partial class ImportStatusDialog : Form
{
public ImportStatusDialog()
{
InitializeComponent();
}
public void updateFileStatus(string path)
{
t_filename.Text = path;
}
public void updatePrintStatus()
{
t_printed.Text = "sent to printer";
}
public void updateImportStatus(string clientName)
{
t_client.Text = clientName;
}
public void updateArchiveStatus()
{
t_archived.Text = "archived";
}
}
:
private void button1_Click(object sender, EventArgs e)
{
ImportStatusDialog nDialog = new ImportStatusDialog();
nDialog.Show();
nDialog.updateFileStatus("test");
Thread.Sleep(1000);
nDialog.updateImportStatus("TestClient");
Thread.Sleep(1000);
nDialog.updatePrintStatus();
Thread.Sleep(1000);
nDialog.updateArchiveStatus();
Thread.Sleep(1000);
nDialog.Close();
}
그리고 심지어는 같이 호출했을 때,
private void button3_Click(object sender, EventArgs e)
{
ImportStatusDialog nDialog = new ImportStatusDialog();
nDialog.Show();
if (this.InvokeRequired)
{
this.Invoke((MethodInvoker)delegate
{
nDialog.updateFileStatus("Test");
});
}
else
{
nDialog.updateFileStatus("Test");
}
Thread.Sleep(1000);
if (this.InvokeRequired)
{
this.Invoke((MethodInvoker)delegate
{
nDialog.updatePrintStatus();
});
}
else
{
nDialog.updatePrintStatus();
}
Thread.Sleep(1000);
if (this.InvokeRequired)
{
this.Invoke((MethodInvoker)delegate
{
nDialog.updateImportStatus("cName");
});
}
else
{
nDialog.updateImportStatus("cName");
}
Thread.Sleep(1000);
if (this.InvokeRequired)
{
this.Invoke((MethodInvoker)delegate
{
nDialog.updateArchiveStatus();
});
}
else
{
nDialog.updateArchiveStatus();
}
Thread.Sleep(1000);
nDialog.Close();
}
처럼 보이는 대화 이 디자이너 (내 예제에서)
그런 식으로 표시됩니다
내가 correnctly 대신 Show() 대화 상자가 표시됩니다의 ShowDialog()를 사용하는 경우,하지만 API의 문서가
지적과 같이 표시하려면이 방법을 사용할 수 있습니다 응용 프로그램의 모달 대화 상자 이 메소드가 호출 될 때 코드는 대화 상자가 나는 그것이 한 후 대화 업데이트는 일어날 것을 의미 특히, 원하는하지 않은
을 닫을 때까지 실행 아닌 다음 다시 닫혔다.
내가 뭘 잘못하고 있니? 이것은 사소한 문제인 것처럼 보이지만 그 해결책이 나를 피합니다. C# GUI 프로그래밍에 익숙하지 않다는 것을 명심하십시오.
또한 Invoke()를 사용하기에 적합한 장소는 무엇입니까? 대화 상자 메서드를 호출 할 때 또는 대화 상자 업데이트 메서드 자체를 호출 할 때 주 폼에서 사용합니까?
버튼 클릭 핸들러에서 기본 UI 스레드를 차단하고 있습니다. 즉, 창을 다시 그릴 수 없습니다. – adrianbanks
어떻게 방지 할 수 있습니까? 이 예제에서 이벤트는 버튼 클릭 핸들러에 의해 발생합니다. 내 현실 세계의 문제 시나리오에서 이벤트는'FileSystemWatcher'에서 왔습니다. 그러나 두 경우 모두 이벤트에 반응하고 싶습니다 – LumenAlbum
근본적으로 잘못하고 있습니다. GUI 프로그래밍은 콘솔 모드 프로그래밍과 전혀 다릅니다. 필요한 부분을 추측 할 수 없으며 실제로 책을 읽을 필요가 있습니다. –