2009-11-21 2 views
0

개체 A와 개체 B가 이진 파일에서 deserialize되었습니다. B는 콜백 함수로 사용되는 private 메서드를 가지고 있으며 A가 이벤트를 발생시킬 때 개인 데이터 멤버에 대한 일부 조작을 수행합니다. A와 B는 직렬화 된 후내 프로그램을 사용하여 serialization을 사용한 후 이벤트 처리가 이상합니다.

Class A 
{ 
    private static A instance; 
    public static A GetInstance(){...}; 
    private A(){} 

    public delegate void SomeCallback(Arg a); 
    public event SomeCallback doCallback; 

    ... 
} 

Class B 
{ 
    private Dictionary<., .> dict; 

    public B() 
    { 
     A.GetInstance().doCallback += new A.SomeCallback(ManipulateDict); 
     ... 
    } 

    private void ManipulateDict(Arg a){...} //breakpoint here 

    public void PrintDict(){...}   
} 

, 레이즈 이벤트 doCallback, 나는 내가 기대하고 있습니다로 실행됩니다 중단 점 라인 (ManipulateDict)를 볼 수 있습니다 때마다 : 기본 구조를 명확히합니다. 그러나 이상한 점은 객체와 다른 메모리 주소를 갖는 'dict'에서 조작된다는 것입니다. 즉, ManipulateDict가 'dict'의 일부 데이터를 성공적으로 업데이트 했더라도 다른 방법, 예를 들어 PrintDict는 여전히 돈이 없습니다. dict에있는 변화를 보지 마라.
직렬화를 사용하지 않으면 이런 일이 발생하지 않고 올바르게 작동합니다. 그러나이 프로그램에 직렬화가 도입되면 상황은 이상하게됩니다. 내가 뭔가 잘못하고 있는거야? 누가 이것을 설명 할 수 있습니까?

대단히 감사합니다!

답변

1

B를 직렬화하면 원래 A.SomeCallback의 메모리 위치가 보존됩니다. A를 비 직렬화하면 재구성 된 객체가 다른 위치에 있으므로 SomeCallback도 새로운 위치에 있습니다. 비 직렬화 된 B는 원래 데이터를 계속 참조하는 이전 A 위치에서 여전히 SomeCallback을 호출합니다. 어쩌면 당신이 deserialization 후 대리자를 다시 연결해야합니다.

+0

설명과 같은 소리가 나에게 의미가 있습니다. 나는 다시 시도했지만 아직 고쳐주지 않았다. 대리인을 다시 연결하는 방법에 대해 자세히 알려주십시오. B의 생성자에서 그 줄을 추가합니다. – fwonce

+0

B에서 deserialize 한 후에 호출 할 수있는 메서드를 제안합니다. 새로 deserialized A를 메서드에 전달하고 이미 수행 방법을 알고있는 것처럼 대리자를 추가합니다. 제 이론이 맞다면 원래의 위임자를 제거해야 SomeCalback의 원래 복사본과 새 복사본이 모두 호출되지 않도록 할 수 있습니다. – Ray

+0

빙고 !!! 레이, 정말 고마워! 정말 고맙습니다. 한 가지 더 : B를 직렬화하기 전에 모든 필요한 대리인을 지우거나 A가 더 많은 청각 장애인 가입자를 얻습니다. – fwonce

0

어떤 직렬화 방법을 사용하고 있습니까? 개체 그래프에 나타날 때마다 각 개체의 새 복사본을 만드는 XMLSerializer와 같은 것을 사용하고있는 것 같습니다. 즉 비 직렬화 할 때 객체의 여러 독립 사본을 가져옵니다. 대신 SoapFormatter를 사용하면 단 하나의 객체 만 가져와 문제를 해결할 수 있습니다.

업데이트 : 대부분의 deserialization 메서드는 기본 생성자를 호출합니다. 기본 생성자가 새 객체를 만듭니다. 이것은 또한 문제가 될 수 있습니다.

+0

안녕하세요. BinaryFormatter를 사용하고 있습니다. – fwonce

+0

나는 싱글 톤을 사용하는 것이 문제의 일부라고 생각한다. B를 만들 때마다 A에 새 이벤트 처리기를 추가하지만 이러한 이벤트 처리기를 다시 제거하지는 않습니다. –

+0

아니요. 사실 B도 싱글 톤입니다. 간단하게 코드 스 니펫을 이렇게 작성합니다. 죄송합니다. – fwonce

관련 문제