나는 진행중인 WinForm 앱을 테스트하기위한 간단한 프레임 워크를 작성 중이다. Application.OpenForms를 사용하여 현재 테스트 단계에서 변경해야하는 컨트롤을 찾습니다. 그러나 때때로 (다른 스레드에 의해) 컬렉션이 수정 된 오류가 발생합니다. 이 컬렉션을 잠그면 일반 UI 스레드 (새 양식 열기 등)가 방해받지 않도록 할 수 있습니까?어떻게 Application.OpenForms를 잠글 수 있습니까?
답변
이 속성을 잠그는 빌드 인 솔루션은 없다고 생각합니다. 이 아닌을 사용하면 수정 된 컬렉션을 찾는 반복자로 인해 발생하는 예외를 방지하기 위해 foreach
-loop을 사용하는 것이 좋습니다. while
-loop (차단 조건은 한 번만 평가되므로 for
-loop이 아님)을 사용하십시오.
처리 할 다른 양식이 있다는 것을 확인한 후 양식이 목록에서 제거되고 ArgumentOutOfRangeException
이 표시 될 위험이 여전히 있습니다. 이 상황을 정상적으로 처리해야합니다.
Int32 index = 0;
while (index < Application.OpenForms.Count)
{
try
{
// Try to copy the form because the index may be or may
// become invalid.
Form form = Application.OpenForms[index];
// Do stuff with the form.
}
catch (ArgumentOutOfRangeException exception)
{
// Handle no longer valid index.
}
index++;
}
이것은 완벽하지 않지만 지금은 더 나은 해결책을 생각할 수 없습니다. 예를 들어 양식 5에있을 수 있으며 일시 중지되고 응용 프로그램이 처음 다섯 개의 양식 중 일부를 닫습니다. 결과적으로 처리되지 않은 양식은 앞쪽으로 이동하고 스레드는 양식 6에서 계속 될 때 코드에 의해 무시됩니다.
어떤 시점에서 모든 양식을 처리해야하는 경우 (응용 프로그램 상태의 스냅 샷과 같이) foreach
-loop을 사용하는 유일한 해결책 일 수 있으며, 실제로 전체 컬렉션을 반복하지 않고 관리 할 때까지 다시 시도하십시오. 예외. 물론 폼이 매우 빠른 속도로 열리고 닫히는 경우 또는 반복 코드에 따라 절대 발생하지 않는 명백한 위험이 있습니다.
링크 된 솔루션은 스레드로부터 안전하지 않습니다. 동일한 스레드에서 열거하는 동안 컬렉션을 수정하는 문제를 피할 수 있습니다. –
Application.OpenForms에 대해 잊어 버리고 대신 관리되지 않는 WinApi를 사용하십시오.
static IEnumerable<Form> EnumOpenForms()
{
foreach (System.Diagnostics.ProcessThread thread in System.Diagnostics.Process.GetCurrentProcess().Threads)
{
List<IntPtr> hWnds = new List<IntPtr>();
EnumThreadWindows(thread.Id, (hWnd, param) => { hWnds.Add(hWnd); }, IntPtr.Zero);
foreach(IntPtr hWnd in hWnds)
{
Form form = Control.FromHandle(hWnd) as Form;
if (form != null)
{
yield return form;
}
}
}
}
[System.Runtime.InteropServices.DllImport("user32.dll")]
static extern bool EnumThreadWindows(int dwThreadId, EnumWindowProc lpEnumFunc, IntPtr lParam);
delegate void EnumWindowProc(IntPtr hWnd, IntPtr parameter);
- 1. 어떻게 페이스 북을 iFrame에 "잠글"수 있습니까?
- 2. 디렉토리를 잠글 수 있습니까?
- 3. 앱에서 화면을 잠글 수 있습니까?
- 4. XNA에서 VertexBuffer를 잠글 수 있습니까?
- 5. 잠글 수 있습니다 (AppDomain.CurrentDomain)?
- 6. C# 메서드 매개 변수를 잠글 수 있습니까?
- 7. 클로저 내에 잠글 수 있습니까()? Lambdas와 코드 출력은 어떻게 생겼습니까?
- 8. GMutex를 두 번 잠글 수 있습니까?
- 9. C#에서 한 줄을 잠글 수 있습니까?
- 10. 어떻게이 속성을 안전하게 잠글 수 있습니까?
- 11. 사용자가 구입할 때까지 파일을 "잠글 수 있습니까?
- 12. ThreadSafeClientConnManager를 잠글 수 없게하는 방법
- 13. Flash Builder 4.5에서 구성 요소를 잠글 수 있습니까?
- 14. MySQL (MyISAM 테이블)에서 테이블을 잠글 수 있습니까?
- 15. 잠금 {} 또는 이와 유사한 구조를 쓰기 전용으로 잠글 수 있습니까?
- 16. Java Web Start에서로드 대화 상자를 잠글 수 있습니까?
- 17. ROWLOCK, UPDLOCK을 사용하여 조인 SQL 구문에서 레코드를 잠글 수 있습니까?
- 18. J2ME에서 "lockSystem"메소드를 사용하여 Blackberry 어플리케이션에서 키패드를 잠글 수 있습니까?
- 19. RoR에서 ActiveRecord 모델을 한번 쓰고 잠글 수 있습니까?
- 20. Javascript 나 HTML로 UIWebView의 방향을 잠글 수 있습니까?
- 21. Java에서 연 파일을 afp 마운트를 통해 잠글 수 있습니까?
- 22. C에서 속성을 얻을 때 잠글 필요가 있습니까?
- 23. 정적 배열 변수를 잠글 필요가 있습니까?
- 24. WPF의 잠글 수있는 서페이스
- 25. 레일 : 많은 시스템 테이블에서 가져온 레코드에 어떻게 데이터를 잠글 수 있습니까?
- 26. 다른 잠글 질문
- 27. iPhone이 화면을 잠글 때 감지합니다.
- 28. 어떻게 C#에서 Windows 키를 비활성화 할 수 있습니까?
- 29. SQLite 데이터베이스를 잠글 수 있습니까? 외부에서 열 수없고 테이블에 행을 추가 할 수 없기 때문에?
- 30. 프로세스가 다른 프로세스가 액세스 할 수 없도록 디스크를 잠글 수 있습니까?
그게 거의 내가 원한 것이 아니지만, 좋은 해결책이없는 것 같습니다. 건배. – Grzenio