[Tip] Collection 바인딩과 InvalidOperationException

Silverlight/Tips 2009.06.04 21:54

실버라이트 어플리케이션을 개발하다보면,
ListBox의 ItemsSource와 List<>나 Collection<>과 같은 IEnumerable류를 바인딩 할 경우가 자주 있습니다.

휴즈플로우에서 진행한 최근 프로젝트 중에서 MVVM 패턴으로 개발한 어플리케이션이 있는데요.
ListBox와 Collection류의 프로퍼티가 바인딩하게 되는 여러 뷰들을 빠른 속도로 전환하다보면,
InvalidOperationException이 발생하였습니다.



Exception에 담겨있는 에러메세지는 "개체의 현재 상태 때문에 작업이 유효하지 않습니다."라는 애매한 메세지였고,
예외가 발생한 곳은 뷰모델의 베이스용으로 구현해 놓은 ViewModelBase의 OnPropertyChanged(...) 함수 내부였습니다.

어플리케이션을 천천히 여유있게 조작하면 문제가 발생하지 않다가, 악의적인 유저로 돌변하여 UI를 이리저리 정신없이
전환시키다 보면 발생하는 Exception인데 해결하기가 여간 어려운게 아니더군요.

이 애매한 문제는 결국 파티션 너머의 공도씨를 호출하여 도움을 받아 해결하였습니다.

수술 전 코드와 수술 후 코드를 보시면서, 어떤 코드가 더 안전한지 이해하실 겁니다.

수술전
public List Photos
{
	get
	{
		return _photos;
	}
	set
	{
		_photos = value;

		OnPropertyChanged("Photos");
	}
}


수술후
public List Photos
{
	get
	{
		return _photos;
	}
	set
	{
		if (_photos != null)
		{
			_photos.Clear();
			_photos = null;
		}

		_photos = value;

		OnPropertyChanged("Photos");
	}
}


콜렉션을 통째로 새 객체로 덮어쓰더라도 전에 사용하고 있던 콜렉션을 Clear 해주고, 변수를 null로 초기화해주면
이런 일이 발생하지 않습니다. 정말 바인딩에서 발생하는 문제들은 타이밍에 관련된 것도 있고 오묘해서 해결하기가
쉽지 않은데 노련한 공도씨가 단박에 해결해 주었네요.

이런 팁은 내용을 이해한 후에 습관화하는 것이 좋을 것 같습니다.

설정

트랙백

댓글

  • 짱구 2009.06.11 17:22 신고 ADDR 수정/삭제 답글

    와우~ 가려웠던 곳이 시원해 졌습니다. Tip 감사합니다. ^^
    안녕하세요. 전에 포스코 뒤에 웹타임에서 실버라이트 교육받았던 교육생입니다. 잘지내시죠?
    블로그엔 종종 들어왔었는데 코멘트는 처음 달아보네요~ ㅎㅎ 게을러서~(눈팅족)
    화면을 롤링하여 보여주는 기능에서 메모리 누수가 일어나던건 알려주셨던 이벤트 -=로 처리했습니다. 정말 고맙습니다.
    요즘 실버라잇으로 이런저런 프로젝트를 진행하는데요. 제가 잘 모르는 부분이 있어서 몇자 적습니다.(이런곳에 올려도 되는지는 모르겠습니당. 양해바랍니당~^^;)

    일단 4개의 xaml 페이지가 있습니다. main.xaml, sub1.xaml, sub2.xaml, sub3.xaml이라고 가정합니다.
    main.xaml에 sub1,2,3이 들어가구요. 1,2,3모두 main의 자식입니다.
    sub1에 4개의 Storyboard가 존재합니다. 첫번째Storyboard가 완료되면 두번재 Storyboard가 실행되고 sub2, sub3의 내용이 갱신되어야 합니다. 두번째 Storyboard가 완료되면 또 다시 sub2, sub3의 내용이 갱신되어야합니다. 물론 세번째 Storyboard도 실행되겠죠~ㅎ
    이러한 기능을 구현하고자 할때 cs파일을 어떻게 작성해야할지 모르겠습니다. 간단할일지도 모르는 질문을 드려 죄송합니다.(반대일수도있지만...^^)
    두서없이 작성해서 내용 파악이 되셨나 모르겠네요. 비슷한 샘플도 없네요.(검색실력부족일수도..)
    작은 도움 부탁드립니다. (^^)(__)
    wy7.kang@partner.samsung.com

    • BlogIcon 길버트 2009.06.19 10:00 신고 수정/삭제

      메일로 답변 드렸습니다. 답변이 늦어 죄송합니다.

  • BlogIcon tohappy 2009.06.16 22:44 신고 ADDR 수정/삭제 답글

    수술전후 내용 재미있구요~ 블로그를 잘 꾸려 나가시는 것 같아 본 받고 갑니다.

    • BlogIcon 길버트 2009.06.19 10:01 신고 수정/삭제

      감사합니다.
      tohappy님은 iPhone App 전문가시니 나중에 iPhone 쪽으로
      도움요청 좀 드리겠습니다.

  • BlogIcon 작은아이! 2009.06.17 05:00 신고 ADDR 수정/삭제 답글

    수술이라는 표현이 참 재미있네요! ㅋㅋㅋ
    간단한 작업으로 보다 안전한 코드가 되었네요 :)

    • BlogIcon 길버트 2009.06.19 10:01 신고 수정/삭제

      감사합니다.
      코드 몇 줄이 어플리케이션의 건강을 좌우하죠!

  • 짱구 2009.06.19 10:40 신고 ADDR 수정/삭제 답글

    답변 메일 잘 받았습니다. 너무 큰 도움 주셔서 감사합니다.
    바쁘신중에도 신경 써주시고...ㅎㅎ 감사 감사 또 감사~ ^^
    보내주신 답변으로 제가 원하던 것을 잘 해결하였습니다.

    혹시 요즘 Virtual Earth 3D(Beta)의 근황을 알수있을까요?
    Bing Map으로 전환된 후로 뭐가 바뀐게 있는건지...
    급변하니까 당췌 따라가기가 버겁네요...ㅎㅎ

    그럼 수고하시구요~ 멋진 답변 다시 한번 감사드립니다~ ^^