영어가 잘 못되어서 제 질문에 대해 간단하게 설명하고 문제를 설명하기 위해 여기에 코드 스 니펫을 붙여 넣으십시오.C# Application.DoEvents는 내 응용 프로그램에서 작동하지 않습니다.
문제는 우리의 winForm 응용 프로그램에서 여러 스레드 문제입니다. 나는 다음의 코드 샘플처럼 간단한 논리를 사용한다.
테스트 코드에는 mainForm에 1 개의 mainForm Form1과 "Start"라는 버튼이 있습니다. 사용자가 버튼을 클릭하면 2 개의 폼 form2와 form3이 2 개의 백그라운드 스레드에서 표시됩니다. form2가 닫히면 Form1이 닫히도록 트리거됩니다. 그러나 form3이 여기에 표시되므로 form3을 혼자서 닫아야합니다. 그래서 form.Closing 이벤트를 처리하고 Application.DoEvents()를 사용하여 사용자가 form3을 닫도록합니다. 그것은 마음에 작동 보인다. 그러나 실제로 form3은 사용자의 작업을 수락 할 수 있지만 form3은 예상대로 닫히지 않습니다.
여기서 form3을 닫을 수없는 이유와 사용자의 닫기 작업을 위해 코드를 수정하는 방법을 설명하십시오.
using System;
using System.ComponentModel;
using System.Threading;
using System.Windows.Forms;
namespace CloseFormFromMainThread
{
public partial class Form1 : Form
{
private Form2 _form2;
private Form2 _form3;
private SynchronizationContext _synchronizationContext;
public Form1()
{
InitializeComponent();
Closing += Form1Closing;
}
void Form1Closing(object sender, CancelEventArgs e)
{
while (_form3 != null)
{
Application.DoEvents();
Thread.Sleep(100);
}
}
private void ButtonStartClick(object sender, EventArgs e)
{
var thread = new Thread(StartForm3);
thread.Start();
var thread2 = new Thread(StartForm2);
thread2.Start();
}
private void StartForm3()
{
Thread.Sleep(200);
var action = new Action(() =>
{
_form3 = new Form2();
_form3.Text = "form 3";
_form3.ShowDialog();
_form3 = null;
});
ExecuteActionInUiThread(action);
}
private void Form1Load(object sender, EventArgs e)
{
_synchronizationContext = SynchronizationContext.Current;
}
private void StartForm2()
{
Thread.Sleep(500);
var action = new Action(() =>
{
_form2 = new Form2();
_form2.Text = "form 2";
_form2.ShowDialog();
Close();
});
ExecuteActionInUiThread(action);
}
private void ExecuteActionInUiThread(Action action)
{
var sendOrPostCallback = new SendOrPostCallback(o => action());
_synchronizationContext.Send(sendOrPostCallback, null);
}
}
}
왜 스레드를 사용하고 있습니까? 모든 것이 UI 스레드에서 실행되는 것 같습니다. 1 단계는 모든 불필요한 복잡성을 없애고 스레드를 제거하는 것입니다. 그렇다면 프로그램이 실제로하는 일을 볼 기회가 있습니다. –
실제 코드에는 Thread.Sleep()이 필요하지 않습니다. 그리고 GUI는 항상 1 스레드이며, 그렇지 않으면 시도하지 마십시오. –
@HenkHolterman : 작동하지 않습니다. WinForms는 다중 스레드를 지원하지 않습니다. 그냥 추락 할거야. – PMF