2009-07-07 3 views
6

저는 크리스마스 2008 이후로 같은 프로젝트를 진행해 왔습니다. 콘솔 응용 프로그램 (트레이스 문장 만 인쇄하는 것)에서 전체 Windows 응용 프로그램. 물론, 괜찮아. 유일한 것은 앱을 실행하는 데 몇 분이 걸릴 수있는 부분이 있다는 것입니다. 사용자 상태 나 오류를 표시하려면 다중 스레드해야합니다. 그러나 나는 어디에서 시작해야할지 모른다.다중 스레드 : UI를 업데이트하여 진행 상황을 표시하는 방법

저는 WPF에서 약간의 UI를 구축했습니다. 그것은 아주 기본적인 것이지만 필요에 따라 확장하고 싶습니다. 이 응용 프로그램은 소스를 선택하고 대상을 선택한 다음 시작을 클릭하여 작동합니다. 프로세스가 진행됨에 따라 목록 상자를 업데이트하고 싶습니다. SQL Server 설치와 마찬가지로, 각 단계의 이름이 완료되면 녹색 확인 표시가 나타납니다.

초보자는 어떻게 멀티 스레딩을 시작합니까? 어떤 라이브러리를 체크 아웃해야합니까? 모든 조언을 크게 주시면 감사하겠습니다.

p.s. 나는 현재 http://www.codeplex.com/smartthreadpool

@Martin이 라이브러리에 대해 읽고 있어요 : 여기 내 응용 프로그램이 구성되어 방법 :

  1. 엔진 : 실행합니다 모든 주요 구성 요소 사전 정의 된 순서
  2. Excel에서 : 도서관 내가 쓴// 읽기 닫기 열/위해 COM을 포장하는 통합 문서 저장
  3. 도서관 : 나는 Excel 데이터를 변환 및 액세스
  4. 을 위해 수험 공부하기 위해 작성한 클래스 : 통합 문서 형식 (총 5)
  5. 비즈니스 클래스의 다른 유형을 이해 도서관
  6. DB 라이브러리 : 당신이 아이디어를
  7. Serialier를 얻을 : 년의 경우 응용 프로그램 충돌

I의 데이터를 저장 Access 데이터에

  • appSettings는을 읽고 ADO.NET을 사용하여 내가 작성한 라이브러리 LINQ에서 ADO.NET까지 모든 것을 사용하여 데이터를 가져 와서 변환 한 다음 출력하십시오. 백그라운드 작업자에 뭔가 예외가 발생합니다 (처리를하거나)하면 어떻게됩니까 :

    내 주요 요구 사항은 내가 진행을

    @Frank을 표시하기 위해 내 UI를 업데이트 할 것입니다? 신청서에 어떻게 통보합니까?

    @ 에릭 리 퍼트 : 예, 지금 조사 중입니다. 내가 복잡한 일을하기 전에.

    자세한 정보가 필요하면 알려주세요. 현재 Unit Test에서이 응용 프로그램을 실행 했으므로 콘솔 응용 프로그램이 맞지 않는다고 생각합니다. 나는 이것을하기 위해 Resharper를 사용한다. 나는 지금 당장 앱을 사용하는 유일한 사람이지만 더 매력적인 인터페이스를 원합니다.

  • +4

    멀티 스레딩 복잡성을 추가하기 전에, 사용자가 단일 스레드 인 동안 사용자가 응답 할 수 있도록 작성하는 방법을 고려해보십시오. 알고리즘을 변경하여 약간의 계산을 수행하고 진행 상황을 확인한 다음 UI를 업데이트하고 중단 한 부분에서 계산을 다시 시작할 수 있습니다. –

    +0

    매우 어려운 데이터베이스 API를 다루는 경우.사용자는 느린 네트워크, 네트워크 장애, 이름 조회 시간 초과를 갖습니다. DB는 바쁠 것입니다. 원시 네트워크 I/O를 다루는 것은 non-blocking/async 모드에서 가능합니다. 그러나 ADO.NET을 통해가는 것은 실제로 가능한 옵션은 아닙니다. – nos

    +0

    @noselasd : 저는 ADO.NET을 조금만 사용하고 있습니다. 백엔드 저장소로 사용하지 않고 있습니다. – Chris

    답변

    0

    총 신규 사용자가 스레딩하는 가장 좋은 방법은 아마도 스레드 풀 일 것입니다.

    EDIT ::
    우리는 이제 좀 더 많은 정보를 얻었으므로, 이전의 대답을 고수 할 것입니다. 보이는 것입니다. 많은 작업을 처리해야하는 것처럼 작업 부하를 처리하는 가장 좋은 방법은 스레드 풀에 스레드를 추가 한 다음 작업이 완료되었는지 확인하고 작업이 특정 순서로 완료되어야하는지 확인하는 것입니다 이전 하나가 완료되면 다음 하나를 간단히 추가 할 수 있습니다.쓰레드 풀은 실제로 이런 종류의 일에 상당히 좋으며이 경우에는 사용하지 않을 이유가 없습니다.

    6

    사용중인 CLR의 버전을 지정하지 않았지만 " BackgroundWorker "제어. 여러 스레드를 구현하는 간단한 방법입니다.

    가장 중요한 부분은, 그것이 당신의 갱신에 응답 a part of the CLR 2.0 and up

    업데이트는 점이다 : 당신은 UI에서 진행 상황을 업데이트 할 수있게하려면 - 진행률 표시 줄에 예를 들면 - 배경 작업자가 완벽합니다. 그것은 내가 생각하는 이벤트를 사용합니다 : ProgressChanged는 상태를보고합니다. 그것은 매우 우아한입니다. 또한 필요한만큼 인스턴스를 보유 할 수 있으며 동시에 모든 인스턴스를 실행할 수 있습니다 (필요한 경우).

    : 예제 프로젝트를 쉽게 설정하고 질문을 테스트 할 수 있습니다. 작업이 코드가 처리하지 않는 예외 를 제기하는 경우, BackgroundWorker에 예외 잡는다과로 전달

    : 나는 (발언 아래에서주의에서 두 번째 단락) 다음, here을 발견했다 RunWorkerCompleted 이벤트 처리기 오류 속성이 System.ComponentModel.. ::. RunWorkerCompletedEventArgs로 표시됩니다.

    +0

    나는 그렇게 생각한다. 그것은 .net 클래스 일뿐입니다. –

    +0

    감사합니다. 나는 그것에 대해 읽을 것입니다. – Chris

    +0

    배경 작업자를 통해 멀티 스레딩에 뛰어 들기 전에 스레드 안전성을 알고 있어야합니다. 다른 스레드에서 한 스레드의 데이터를 직접 액세스/업데이트하는 것은 위험하고 안전하지 않다는 것을 알고 있어야합니다. 여기에있는 다른 링크는 잠금과 비슷한 것을 소개합니다. – nos

    0

    This page은 스레딩의 좋은 요약입니다.

    소리가 아주 복잡 할 필요는 없습니다. 작업을 시작한 후 끝낸 시점을 알고 싶다면 새 스레드를 만들고 몇 줄의 코드 만 있으면됩니다. 그것은 당신의 작업을 실행합니다. 그러면 작업이 완료되면 UI 스레드가 따라 다니고 주기적으로 검사 할 수 있습니다.

    +0

    @ Jason : 그 이상입니다. 나는 대략 5000+ 통합 문서를 처리하고 UI가 거기 앉는 때 통합 문서가 가공되고 있다는 것을 알고 싶으면, 등등. – Chris

    +0

    필요가 단순하면 휘발성 물질을 사용하여 최소한의 노력으로 스레드간에 값을 전달할 수 있습니다. 예 : 통합 문서 목록이있는 경우 현재 통합 문서의 인덱스를 나타내는 int를 사용하여 진행률을 나타낼 수 있습니다. "volatile int myIndex;"로 선언함으로써 스레드간에 안전하게 액세스하기 위해 잠금을 사용할 필요가 없습니다. UI 스레드에서 두 번째로 몇 번 호출하는 Forms.Timer를 추가하고 myIndex를 읽고보고함으로써 UI를 업데이트 할 수 있습니다. 좀 더 복잡한 데이터가 필요하다면 클래스에 넣고 모든 액세스를 잠급니다. –

    +0

    휘발성은 bool, int와 같은 몇 가지 유형에만 사용할 수 있습니다. –

    0

    Concurrent Programming on Windows은 주제에 관한 최고의 책입니다. 유명한 멀티 쓰레딩 전문가 인 Joe Duffy가 쓴 글. Windows 스레드 스케줄러가 작동하는 방식부터 .NET Parallels Extensions Library에 이르기까지 알아야 할 모든 것.

    +0

    초보자는 어떻게 멀티 스레딩을 시작합니까? 나는이 책을 의심한다. – Nick

    0

    당신이 크로스 스레딩 문제를하지 않도록 UI를 업데이트하기 위해 대표단을 만들 기억하고 메모/파워 포인트를 많이해야하는 경우 UI가 유치장에게/또한

    을 동결 나타나지 않습니다/등 등

    내 대학원에 http://ist.psu.edu/courses/SP04/ist411/lectures.html

    0

    제이슨의 링크가 좋은 기사입니다에서 모든 강의 노트를 제안 할 수 있습니다. 주의해야 할 점은 UI는 기본 UI 스레드에 의해서만 업데이트 될 수 있다는 점입니다. 작업자 스레드에서 UI를 수행하려고하면 크로스 스레딩 예외가 발생합니다. BackgroundWorker 컨트롤은 이벤트에 도움이되지만 Control.Invoke (또는 Control.Begin/EndInvoke)도 알고 있어야합니다. UI 스레드의 컨텍스트에서 대리자를 실행하는 데 사용할 수 있습니다.

    다른 스레드에서 동일한 코드/변수에 액세스하는 방법을 읽어야합니다. 이러한 문제 중 일부는 추적하기 위해 간헐적으로 발생하는 버그를 유발할 수 있습니다.

    휘발성 키워드는 변수 액세스의 '신선함'만 보장합니다. 예를 들어, 변수의 읽기 및 쓰기가 스레드 또는 프로세서 캐시가 아닌 주 메모리에서 이루어 지도록하거나 메모리 모델의 다른 '특징'. 스레드가 읽기 - 업데이트 - 쓰는 프로세스 (예 : 변수 값 변경) 중에 다른 스레드에 의해 인터럽트되는 것과 같은 문제를 중지하지 않습니다. 이로 인해 2 개의 스레드가 변수에 대해 다른 값을 가지거나 오류가 발생하여 값이 손실 될 수 있습니다. 2 개의 스레드는 서로 다른 값을 가져야 할 때 같은 값을 갖습니다. 잠금/모니터 (또는 다른 스레드 동기화 메소드, 대기 핸들, 인터록 증가/감소 등)를 사용하여 이러한 유형의 문제를 방지 할 수 있습니다. 단 하나의 스레드 만 변수에 액세스 할 수 있습니다. (모니터도 암시 적으로 휘발성 읽기/쓰기를 수행한다는 장점이 있습니다.)

    다른 사람이 지적했듯이 백그라운드 스레드가 완료 될 때까지 기다리는 동안 UI 스레드를 차단하지 않도록해야합니다. 그렇지 않으면 UI가 응답하지 않게됩니다 . 작업자 스레드가 진행 중이거나 완료되었음을 나타내는 UI가 구독하는 이벤트를 발생 시키면 이렇게 할 수 있습니다.

    매트

    0

    Typemock는 멀티 스레딩 문제를 도와 Racer라는 새로운 도구가 있습니다. 조금 익숙하지만 포럼이나 다른 온라인 포럼에서 도움을 얻을 수 있습니다. (이상하게 떠오르는 질문은 stackoverflow :-))

    0

    저는 멀티 스레딩의 초보자입니다. 배경 작업자가 아마도 최선의 선택 일 것입니다. 이벤트 구독을 통해 작동합니다. 사용 방법에 대한 기본 사항은 다음과 같습니다.

    • 먼저 인스턴스화 새로운 백그라운드 작업자 배경 노동자 주요 이벤트에 코드에서
    • 구독 방법 :
      • DoWork :이
      • ProgressChanged를 처리하는 데 시간이 오래 걸립니다 그 어떤 코드를 포함해야 : DoWork에 등록 된 메소드 내부에서 ReportProgress()를 호출 할 때마다 호출됩니다.
      • RunWorkerCompleted : DoWork 메소드가 완료되면 활성화됩니다.

    시간이 많이 걸리는 프로세스를 실행할 준비가되면 배경 작업자의 RunAsync() 메서드를 호출합니다. 이렇게하면 별도의 스레드에서 DoWork 메소드가 시작되어 ProgressChanged 이벤트를 통해 진행 상황을보고 할 수 있습니다. RunWorkerComplete가 완료되면 호출됩니다.

    DoWork 이벤트 메서드는 CancelPending 속성 값을 검사하여 사용자가 어떻게 프로세스를 취소 할 것인지 (CanceLAsync()가 호출 되었음)를 요청했는지 여부를 확인할 수도 있습니다.

    관련 문제