Silverlight/Tips

[Tip] Collection 바인딩과 InvalidOperationException

길버트리 2009. 6. 4. 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로 초기화해주면
이런 일이 발생하지 않습니다. 정말 바인딩에서 발생하는 문제들은 타이밍에 관련된 것도 있고 오묘해서 해결하기가
쉽지 않은데 노련한 공도씨가 단박에 해결해 주었네요.

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