2011-11-17 5 views
4

스레드에서 오랜 시간 작업을 수행하고 진행 상황을 출력하기 위해 진행률 표시 줄이나 카운터에 표시 할 수있는 여러 클래스가 있습니다.진도 정보를 제공하는 클래스에는 어떤 방법이 있나요?

인터페이스에 정의 된 이벤트 나 대리자를 사용할 수는 있지만 모든 구현에 대해 똑같은 FireEvent 코드를 작성하여 이벤트가 null인지 확인한 다음 그렇지 않은 경우 확인해야합니다.

추상 클래스를 사용하는 것은 나쁘다. 그와 같은 기능은 최상위 클래스에 속하지 않으므로 다시 다른 위치에 구현해야한다는 의미입니다.

어디에서나 코드 중복없이 가장 재사용 가능한 방법으로 어떻게 할 수 있습니까?

+3

그런 기능이 기본 클래스에 속하지 않는 이유는 무엇입니까? 기본 클래스의 핵심은 파생 클래스간에 공유 기능을 제공하는 것입니다. –

+0

모든 클래스가 동일한 방식으로 진행률을보고하는 이유는 무엇입니까? – vidstige

+0

@vidstige 업데이트 할 진행률 표시 줄을 지정하고 진행률 막대를 업데이트 할 수 있습니다. 모든 클래스가 지정된 진행률 막대를 업데이트합니다. 그들은 모두이 예에서 같은 방법으로 진행 상황을보고합니다. –

답변

2

나는 보통 뷰와 뷰 모델에 대해 알 수 있도록 모델 사이의 관계. 이 예에서는 진행 대화 상자에 IProgress 인터페이스에 대한 참조가 있습니다. 그런 다음 ProgressChanged 이벤트에 연결되므로 뷰는 필요한 경우 자체를 업데이트 할 수 있습니다. 이것의 가장 큰 장점은 여러 클래스 내의 코드가 중복되지 않는다는 것입니다. 얼마나 많은 코드가 남았는지 알려주는 코드 만 해당 클래스 안에 있습니다. 이렇게하면 진행 상황을 자주 내보내는 클래스의 진행 업데이트를 매우 쉽게 클램핑 할 수 있습니다.

interface IProgress 
{ 
    event EventHandler ProgressChanged; 
    int ProgressTarget { get; } 
    int CurrentProgress { get; } 
} 

그리고 구현 클래스 :

그냥 당신에게 나는 보통 무엇 아이디어를 제공합니다. 나는 그것이 작동해야하는지조차 모르겠다 -이 인터페이스를 구현하는 방법에 대한 인상을 주기만하면된다.

class StreamCopier: IProgress 
{ 
    private Stream _source; 
    private Stream _destination; 

    public StreamCopier(Stream source, Stream destination) 
    { 
     _source = source; 
     _destination = destination; 
    } 

    public void WriteAll() 
    { 
     int b; 
     while ((b = _source.ReadByte()) != -1) 
     { 
      _destination.WriteByte((byte)b); 
      EventRaiser.Raise(ProgressChanged, this); // Just one call here! Can't be less 
     } 
    } 

    public event EventHandler ProgressChanged; 

    public int ProgressTarget { 
     get { return (int)_source.Length; } 
    } 

    public int CurrentProgress { 
     get { return (int)_destination.Position; } 
    } 
} 

그리고 나서 EventRaiser 클래스입니다. 핸들러 참조가 매개 변수 스택에서 전달되는 방식에 주목하십시오. 따라서 'tmp'에 대한 스레드 안전 복사가 필요하지 않습니다! :)

static class EventRaiser 
{ 
    public static void Raise(EventHandler handler, object sender, EventArgs args) 
    { 
     handler(sender, args); 
    } 

    public static void Raise(EventHandler handler, object sender) 
    { 
     Raise(handler, sender, EventArgs.Empty); 
    } 
} 
+0

감사합니다. 그러나 이것이 내가 실제로 피하려고하는 것입니다.진행 상황 변경 이벤트가 시작될 때마다 null을 확인해야합니다. 일반적으로 RaiseEvent 함수에 있지만이 때마다 구현해야합니다. 많이는 아니지만 차라리 불을 피우고 RaiseProgressChanged 메서드를 사용할 수 있다는 것을 잊어 버렸습니다. 어딘가에 필요할 때마다 구현할 필요가 없습니다. – Darcara

+0

그래, 그래도 나는 이것도 싫어. 그것은 언어에 더 많은 문제입니다. 내가 어떻게 대처했는지 보려면 편집을 참조하십시오. – vidstige

+0

어쩌면 질문에 대답하지는 않지만 그럼에도 불구하고 매우 흥미 롭습니다. 그것을 설명하는 추가 노력을 위해 +1. – Cyberherbalist

관련 문제