문제

나는 결코 완전히 행복하는 방식에는 예외 처리 작품,많은 예외를 시도/을 잡을 제공하는 테이블(스택 해제,등등), 하지만 그것은 휴식의 많은 OO 모델에서 처리합니다.

어쨌든,여기에 문제가:

말 당신은 몇 가지고 있는 클래스는 랩이나 포함되어 있 네트워크로 연결된 파일 IO 작업(예:읽기와 쓰기하는 어떤 파일에는 몇 가지 특정 UNC 길이 어딘가에).다양한 이유로 당신을 원하지 않는 사람들 IO 작업이 실패하는,그래서 당신이 감지하는 경우는 그들은 실패를 재시도하고 당신은 유지시까지 그들을 그들은 성공하거나 당신에 도달한다.이미리 RetryTimer 클래스는 인스턴스화할 수 있습과 잠하는 데 사용은 현재 스레드 사이에 다시 시도 횟수를 결정할 때 시간 제한 기간이 경과,etc.

문제는 당신의 무리가 있 IO 작업에 여러 가지 방법의 이 클래스고,필요하신을 감싸는 그들 각각에/재시도 논리입니다.

다음 예제 코드:

RetryTimer fileIORetryTimer = new RetryTimer(TimeSpan.FromHours(10));
bool success = false;
while (!success)
{
    try
    {
        // do some file IO which may succeed or fail
        success = true;
    }
    catch (IOException e)
    {
        if (fileIORetryTimer.HasExceededRetryTimeout)
        {
            throw e;
        }
        fileIORetryTimer.SleepUntilNextRetry();
    }
}

그래서,당신은 어떻게 당신이 중복되지 않도록하기 위해 대부분의 이 코드는 모든 파일에 대해 IO 가동 클래스 전체에서?나의 솔루션을 사용하는 익명의 대리인 블록고 하나의 클래스의 메소드에 실행 대리인 블록 전달됩니다.이용하는 것과 같은 이에서 다른 방법:

this.RetryFileIO( delegate()
    {
        // some code block
    } );

나는 다음과 같이 다소,하지만 그것이 나뭇잎이 많이 있습니다.내가 듣고 싶은 사람들이 어떻게 해결할 것이 이런 종류의 문제입니다.

도움이 되었습니까?

해결책

이처럼 우수한 기회에 모습을 가지 측면이 지향 프로그래밍입니다.여기에 좋은 기사 AOP 습니다.NET.일반적인 아이디어를 추출하는 간 기능적인 관심을(즉다시 시도 x 시간)으로 별도의 클래스고 그 다음 당신은 주석이 어떤 방법을 수정할 필요가에서 자신의 행동하는 방법입니다.여기에 어떻게 보일 수 있습니다(좋은 확장자 방법에 Int32)

[RetryFor( 10.Hours() )]
public void DeleteArchive()
{
  //.. code to just delete the archive
}

다른 팁

그 궁금,당신은 무엇을 느낌을 당신의 방법 잎을 원하는가?대체할 수 있는 익명의 대리인으로..이름?대리자가

    public delegate void IoOperation(params string[] parameters);

    public void FileDeleteOperation(params string[] fileName)
    {
        File.Delete(fileName[0]);
    }

    public void FileCopyOperation(params string[] fileNames)
    {
        File.Copy(fileNames[0], fileNames[1]);
    }

    public void RetryFileIO(IoOperation operation, params string[] parameters)
    {
        RetryTimer fileIORetryTimer = new RetryTimer(TimeSpan.FromHours(10));
        bool success = false;
        while (!success)
        {
            try
            {
                operation(parameters);
                success = true;
            }
            catch (IOException e)
            {
                if (fileIORetryTimer.HasExceededRetryTimeout)
                {
                    throw;
                }
                fileIORetryTimer.SleepUntilNextRetry();
            }
        }
    }

    public void Foo()
    {
        this.RetryFileIO(FileDeleteOperation, "L:\file.to.delete" );
        this.RetryFileIO(FileCopyOperation, "L:\file.to.copy.source", "L:\file.to.copy.destination" );
    }

당신도 사용할 수 있는 더 OO 접근 방식:

  • 만드는 기본 클래스는 오류 처리하고 통화를 추상적인 방법을 수행하는 구체적인 작동합니다.(템플릿 방법 패턴)
  • 만들기 콘크리트 클래스를 위해 각각의 작업입니다.

이 이름을 지정의 각 유형의 작업을 수행하고 당신에게 명령 패턴 작업으로 표현되어 왔다.

여기에 내가 무슨 짓을했는지였습니다.그것은 아마도 다른 곳에서 수행되는 더 나은 것 같지만 아주 깨끗하고 재사용할 수 있습니다.

나는 유틸리티는 방법에는 다음과 같습니다.

    public delegate void WorkMethod();

    static public void DoAndRetry(WorkMethod wm, int maxRetries)
    {
        int curRetries = 0;
        do
        {
            try
            {
                wm.Invoke();
                return;
            }
            catch (Exception e)
            {
                curRetries++;
                if (curRetries > maxRetries)
                {
                    throw new Exception("Maximum retries reached", e);
                }
            }
        } while (true);
    }

후에 응용 프로그램,내가 사용하는 c#'s 는 람다 식 구문을 유지하는 것을 깔끔:

Utility.DoAndRetry( () => ie.GoTo(url), 5);

이 통화 내 방법과 다시 시도까지 5 번입니다.에서 다섯 번째 시도는 원래 예외는 다시 throw 의 내부에 다시 시도 예외는 아니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top