2010-02-16 3 views
0

두 가지 방법이있는 웹 서비스가 있습니다.한 번만 실행하는 이벤트 처리기/상태 시스템 설계 중?

RetrieveFirstLevelOptions() 및 RetrieveSecondLevelOptions (int levelOneOption).

GUI에는 FirstLevelOptionsCombo 및 SecondLevelOptionsCombo의 두 가지 콤보 상자가 있습니다.

RetrieveFirstLevelOptions()에 요청을해야 할 때 초기화 단계에 대한 제어 흐름을 생성하는 데 문제가 있습니다. 그런 다음 결과가 나오면 RetrieveSecondLevelOptions (기본 levelOneOption = 0)를 호출합니다.

문제는 모든 것이 비동기 적으로 발생하기 때문에이 동작을 처음부터 한 번만 수행하면 좋은 방법이 무엇인지 알 수 없습니다.

내가 선호하는 옵션은 RetieveFirstLevelOptionsCompleted 이벤트에 두 번째 이벤트 처리기를 연결하고 한 번만 실행 한 후에 자체를 제거하도록하는 옵션입니다. 그러나 그런 행동은 불가능한 것처럼 보입니다.

또 다른 옵션은 초기화 단계에 있는지 여부를 나타내는 부울 플래그를 갖는 것입니다. 그렇다면 RetrieveFirstLevelOptionsCompleted의 핸들러가 일부 추가 로직을 실행합니다. 그러나이 아이디어는 모든 이벤트 처리기가 상태 정보를 확인하고 현재 상태에 따라 다른 작업을 수행해야하는 것처럼 보입니다. 제어 흐름이 하향식으로 보이기 때문에 이것은 나쁜 설계 인 것 같습니다.

한 지점에서 결정을 내리는 중앙 집중식 제어 흐름 메커니즘이 필요합니다. 그러나 모든 것이 비동기 적으로 실행될 때 어떻게 할 수 있습니까?

+1

왜 "가 한 번 실행 된 후 이벤트 핸들러를 제거"불가능 얻을 수있다 :

어떤 이유로이 작동하지가되어 있습니까? –

+0

견적은 "한 번만 실행하면 자체 제거"입니다. 이 기능을 작동시키는 방법을 안다면 분명히보고 싶을 것입니다. 그렇지 않으면, 우리는 상태 머신 아이디어로 되돌아갑니다. – Rire1979

답변

1

"RetieveFirstLevelOptionsCompleted 이벤트에 두 번째 이벤트 처리기를 연결하고 한 번만 실행 한 후에 자체를 제거하는 것이 좋지만 이러한 동작은 불가능합니다."

class Example 
{ 
    SomeWebService myService; 

    Example() 
    { 
     // do stuff 
     myService.RetrieveFirstLevelOptionsCompleted += MyHandlerMethod; 
    } 

    void MyHandlerMethod(object sender, RetrieveFirstLevelOptionsCompletedEventArgs e) 
    { 
     // do stuff 
     myService.RetrieveFirstLevelOptionsCompleted -= MyHandlerMethod; 
     // potentially attach next event handler for all subsequent calls 
     myService.RetrieveFirstLevelOptionsCompleted += MyHandlerMethod2; 
    } 
} 
+0

나는 그 접근법을 사용하곤했지만 항상 나에게 해킹처럼 보였다. 여기에는 두 가지 기본적인 문제점이 있습니다 : (1) 논리가 다양한 장소로 확산되기 때문에 현재 어떤 핸들러가 연결되어 있는지 추적하기가 어렵습니다. (2) 첫 번째 호출이 완료되기 전에 myService.RetrieveFirstLevelOptions에 대한 두 번째 호출을 수행하면 디버그하기가 매우 어려울 예상치 못한 동작이 발생하게됩니다. 특정 콜백을 허용하는 래퍼는 이해하기 쉽고 잘못 이해하기가 어렵습니다. –

+0

어느 정도 동의하지만, 구현은 달성하려는 목표에 따라 다릅니다. 이 답변은 이벤트 처리기를 제거 할 수 없다는 자신의 견적에 대해 더 자세히 설명되었습니다. 나는 간단한 if (초기화 된) 체크를 사용하는 것보다 더 나은 방법이 많은 상황을 발견하지 못했다. – jeffora

+0

이벤트 핸들러를 제거하는 데 문제가 있었지만 그 원인이 XAML이라는 것을 깨달았다. XAML에서 이벤트를 정의 할 때처럼 - = handler를 사용하여 쉽게 제거 할 수없는 것처럼 보입니다. –

1

일반적으로 이와 같은 상황에서 사용하는 패턴은 콜백 메서드를 허용하는 Async 웹 서비스 프록시 메서드 주위에 래퍼를 만드는 것입니다. 당신이 RetrieveFirstLevelOptions()를 호출 할 때

public void RetrieveFirstLevelOptions(Action callback) 
{ 
    client.RetrieveFirstLevelOptionsAsync(callback); 
} 

void client_RetrieveFirstLevelOptionsCompleted(object sender, AsyncCompletedEventArgs e) 
{ 
    var callback = e.UserState as Action; 
    if (callback != null) 
    { 
     callback(); 
    } 
} 

그래서, 당신은 당신이 한 번만 실행하려는 콜백을 전달하고 혹시 안 가지고 : 콜백 방법은 다음 지금처럼 RetrieveFirstLevelOptionsAsync() 메서드에 전달됩니다 여러 번 호출되는 것에 대해 걱정할 필요가 있습니다. 아마도 콜백 내에서 RetrieveSecondLevelOptions()에 전화를 걸었을 것입니다.

+0

내가 묻는 것에 신경 쓰지 않는다면이 메커니즘은 초기화 단계의 일부로 응용 프로그램 수명 동안 콜백이 정확히 한 번만 호출되도록 어떻게 보증합니까? – Rire1979

+0

기술적으로는 그렇지 않습니다. 필자의 가정은 첫 번째 호출 (RetrieveFirstLevelOptions)이 여러 번 생성 될 수 있지만 초기화 중에 두 번째 호출 만 만들고 싶어하기 때문에 이것이 유일한 관심사라는 것입니다. (그렇다면 걱정할 이유가 무엇입니까?) 그래서이 시나리오에서는이 래퍼를 사용하여 초기화하는 동안 첫 번째 호출을 호출하고 호출해야 할 때마다 두 번째 호출 (RetrieveSecondLevelOptions)이 생성되지 않을 것이라고 확신 할 수 있습니다 FirstLevelOptions를 검색하십시오. –

관련 문제