2013-04-10 3 views
0

내 실버 라이트 애플리케이션에서 GetListCallBack 메서드를 비동기 서비스 호출의 완료 이벤트에 이벤트 핸들러로 첨부하는 Repository 클래스의 GetEmployees 대리자 매개 변수에 전달하는 중입니다.이벤트 핸들러가 구독 취소되지 않음

EmpViewModel 등급 :

public class EmpViewModel 
{ 
    private IRepository EMPRepository = null; 

    //constructor 
    public EmpViewModel 
    { 
    this.EMPRepository= new Repository(); 
    } 

    public void GetList() 
    { 
    this.EMPRepository.GetEmployees(xyz, this.GetListCallBack); 

    } 

    public void GetAnotherList() 
    { 
    this.EMPRepository.GetEmployees(pqr, this.GetAnotherListCallBack); 

    } 


    private void GetListCallBack(object sender, GetListCompletedEventArgs args) 
    { 
     if (args.Error == null) 
     { 
      this.collection1.Clear(); 
      this.collection1 = args.Result; 
     } 
     else 
     { 
      //do sth 
     } 
    } 

    public void GetAnotherListCallback(object sender, GetListCompletedEventArgs args) 
    { 
    //do sth with collection1 

    } 

} 

저장소 클래스 : 이제

public class Repository : IRepository 
{ 

    private readonly ServiceClient _client=null ; 

    public Repository() 
    { 
     _client = new ServiceClient(Binding, Endpoint); 
    } 

    public void GetEmployees(int xyz, EventHandler<GetListCompletedEventArgs> eventHandler) 
    { 
     _client.GetListCompleted -= eventHandler; 
     _client.GetListCompleted += new EventHandler<GetListCompletedEventArgs>(eventHandler); 
     _client.GetListAsync(xyz); 
    } 
} 

때 나는이 같은 클래스 EmpViewModel에 다른 방법 GetAnotherList()를 호출하는 경우, 다음 완성 된 GetList() 메소드를 호출 메서드가 호출되기 전에 GetAnotherListCallBack 메서드가 다시 호출됩니다.

두 방법 모두 이벤트에 가입하면 이러한 현상이 발생할 수 있습니다.

보시다시피, 나는 이벤트 핸들러를 콜백 이벤트에서 명시 적으로 구독 취소했으나 여전히 이벤트 핸들러가 호출 중입니다. 누구나 내가 잘못 될 수있는 곳을 제안 할 수 있습니까?

편집 :

내가 대신

을 발사됩니다이 Repository 클래스의 다른 인스턴스 만 attched 콜백 메소드에 전달되는 두 콜백 방법으로 잘 작동 Repository 메소드를 호출 this.EMPRepository를 사용하는 로컬 변수를 사용하는 경우
public class EmpViewModel 
{ 

public void GetList() 
{ 
    EMPRepository = new Repository(); 
    EMPRepository.GetEmployees(xyz, this.GetListCallBack); 
} 

public void GetAnotherList() 
{ 
EMPRepository = new Repository(); 
EMPRepository.GetEmployees(pqr, this.GetAnotherListCallBack); 
} 

-------- 
+0

'ServiceClient' 클래스의 코드를 바꿀 수 있습니까? 그것은 고쳐 져야하는 것입니다. –

+0

@ MD.Unicorn ServiceClient 클래스는 서비스 참조가 추가 될 때 VS에 의해 자동 생성됩니다. – Raj

답변

1

첫째

_client.GetListCompleted += new EventHandler<GetListCompletedEventArgs>(eventHandler); 

가 (기능 POI에서 본 보기의 NT)는 다음과 같습니다.

_client.GetListCompleted += eventHandler; 

이제 문제가 즉시 나타납니다. 귀하의 코드는 다음과 같습니다 :

_client.GetListCompleted -= eventHandler; 
_client.GetListCompleted += eventHandler; 

다음 행에 이벤트 처리기를 추가하는 이유는 무엇입니까?

이전 이벤트 처리기를 제거하고 새 이벤트 핸들러를 추가하고 싶습니다. 그래서 당신의 함수는 이전 이벤트 핸들러에 대한 Delegate를 제거해야합니다. 다음과 같은 것 :

public void GetEmployees(int xyz, EventHandler<GetListCompletedEventArgs> oldEventHandler, EventHandler<GetListCompletedEventArgs> newEventHandler) 
{ 
    _client.GetListCompleted -= oldEventHandler; 
    _client.GetListCompleted += newEventHandler; 
    _client.GetListAsync(xyz); 
} 

그런가요?

당신이 ServiceClient.GetListCompleted을 제어 할 수 있다면, 왜 event 키워드를 제거하지와 마찬가지로, 그 대리자를 할당합니다 대리자 만 불려 갔을 경우

public void GetEmployees(int xyz, EventHandler<GetListCompletedEventArgs> eventHandler) 
{ 
    _client.GetListCompleted = eventHandler; 
    _client.GetListAsync(xyz); 
} 

또는 ... GetListASync 당 한 번 :

public void GetEmployees(int xyz, EventHandler<GetListCompletedEventArgs> eventHandler) 
{ 
    _client.GetListCompleted += (sender, args) => 
    { 
     eventHandler(sender, e); 
     _client.GetListCompleted -= eventHandler; 
    }; 
    _client.GetListAsync(xyz); 
} 
+0

답장을 보내 주셔서 감사합니다. 당신에 의해 제기 된 모든 포인트는 실제로 자리하고 있으며 매우 도움이됩니다.마지막 코드 블록은 확실히 이벤트 핸들러 구독을 취소하는 훌륭한 방법입니다. 그러나이 방법을 사용한 후에도 동일한 문제에 직면하고 있으며 콜백 메소드가 차례로 호출됩니다. 그러나 'Repository'메서드를 호출하기 위해 'this.EMPRepository'를 사용하는 대신 로컬 변수를 사용하면 두 개의 CallBack 메서드가 'Repository'클래스의 다른 인스턴스에 전달되고 Attched CallBack 메서드 만 실행되기 때문에 제대로 작동합니다. – Raj

관련 문제