내 응용 프로그램에서 숨겨진 dummyForm
이라는 숨겨진 시작은 기본 UI 스레드를 추적하기 위해 작성된 것입니다. 따라서 새 양식을 만들려고하면 더미 양식에서 InvokeRequired
을 사용하여 새 양식을 만들 때 기본 UI 스레드에 있는지 확인하십시오.WinForms를 사용한 스레딩?
frmStart
양식을 직접 인스턴스화 한 후에 나는 frmStart.InvokeRequired
을 확인하고 false로 설정되므로 여기에서 호출 할 필요가 없습니다 (동일하게는 dummyForm.InvokeRequired
).
frmMyDialog.InvokeRequired = false
dummyForm.InvokeRequired = false
frmStart.InvokeRequired = true
:
using(Create frmMyDialog on main UI thread)
{
frmMyDialog.Show(frmStart);
}
이 크로스 스레드 예외 여기에 이상한 일을 던질 것입니다 :
그 다음이 같은 부모/소유자 무언가로 frmStart
를 사용하는 frmMyDialog
있어 그리고 이것은 이 거짓 일 때 frmStart
을 만들 때 거짓인지 확인하는 중입니다.
frmMyDialog.InvokeRequired
은 항상 dummyForm.InvokeRequired
과 같아야합니다. 여기서 무슨 일이 일어나고있는거야?
첫 번째 인스턴스를 만든 후에 frmStart
과 dummyForm
이 전혀 다시 생성되지 않았 음을 확인했습니다.
EDIT1 :
이 응용 프로그램이 시작하는 방법입니다 MyClientMain 클래스의 생성자는 MainControl라는 정적 클래스에서 설치 프로그램을 실행합니다
public static void Main(string[] args)
{
_instance = new MyClientMain(parameters);
Application.Run(_instance);
}
. MainControler는 설정 방법이 같은 dummyform합니다 실체화 :
if (_dummyForm == null)
_dummyForm = new Form();
이 후에는 로그인 양식은 로그인을 처리 할 수행이 양식은 멀티 스레드입니다. 로그인이 끝나면 MainController가 다시 호출되어 frmStart가 들어있는 기본 MDI windo를 인스턴스화하고 엽니 다. 우리가 같은 스레드에 있는지 확인하려면 다음을 수행하십시오.
public static StartApplication()
{
if (_dummyForm.InvokeRequired)
_dummyForm.Invoke(new MethodInvoker(delegate { OpenMainOrbitWindow(); }));
//Instanciate mainform and frmStart then open mainForm with frmStart as a MDI child
}
여기에 멀티 스레딩이 없습니다.
그런 다음 서비스가 오프라인 상태가되면 이벤트가 트리거되고 frmMyDialog를 팝업해야하지만 사용하면됩니다.ShowDialog를()는 대화 상자가 다음과 같이 부모/소유자를 찾을 수 최우선 형태의 뒤에 배치 및 설정됩니다 다음을 생성 시작 및 :
public static Form GetActiveForm()
{
Form activeForm = Form.ActiveForm;
if (activeForm != null)
return activeForm;
if (MainOrbitForm.TopMost)
return MainOrbitForm;
else
{
FormCollection openForms = Application.OpenForms;
for (int i = 0; i < openForms.Count && activeForm == null; ++i)
{
Form openForm = openForms[i];
if (openForm.IsMdiContainer)
return openForm.ActiveMdiChild;
}
}
if (_patientForm != null)
{
if (_patientForm.TopMost)
return _patientForm;
}
return null;
}
public static string ShowOrbitDialogReName()
{
frmMyDialog myDialog;
Form testForm;
//Makes sures that the frmOrbitDialog is created with the same thread as the dummyForm
//InvokeRequired is used for this
using (myDialog = MainController.CreateForm<frmOrbitDialog>())
{
//Settings...
testForm = GetActiveForm();
myDialog.ShowDialog(GetActiveForm(testForm));
}
}
문제는
myDialog.InvokeRequired = false
testForm.InvokeRequired = true;
MainController.DummyForm.InvokeRequired = false;
Edit2가 있다는 것입니다 dummyform : 우리가 mainform을 만들 성공 로그인 후
dummyForm.InvokeRequired = false
Thread.CurrentThread.ManagedThreadId = 9
_mainForm.InvokeRequired = false
MainControl.DummyForm.InvokeRequired = false
Thread.CurrentThread.ManagedThreadId = 9
지금까지 모든 것이 잘 보입니다. 그런 다음 콜백 (WCF)를 수신하고 이벤트는 동일한 스레드에 frmMyDialog (호출이 dummyForm에 사용) 후 ShowDialog를 사용하는 생성 :이 CrossThreadException을 던졌습니다
frmMyCustomDialog.ShowDialog(_mainForm)
를이는 모습입니다 이 시점에서 같이 :
_mainForm.InvokeRequired = true
frmMyCustomDialog.InvokeRequired = false
MainControl.DummyForm.InvokeRequired = false
Thread.CurrentThread.ManagedThreadId = 12
MainControl.DummyForm이 true가 아닌 이유는 무엇입니까? ManageThreadId는 9가 아니라 12입니까?
더보기 * 예외 상황과 관련된 양식을 작성하는 방법에 대한 * 실제 * 코드를 표시하십시오. InvokeRequired는 주 UI 스레드가 아니라 컨트롤/폼이 작성된 스레드에 바인딩됩니다! – Jan
Application.Run을 여러 번 호출합니까? 난 당신이 단지에 관계없이 상태의 호출을 강제하면 어떻게됩니까에서 :) – Jodrell
@Jodrell 탄원 EDIT1 – Banshee