LINQ 이중 슬립 현상

분명 제가 잘못한것이겠지만 그냥 답변을 바라기 보다는 비슷한 현상을 겪어보신분 있나 해서 올려봅니다.

이중슬립 : 전자의 운동이 관찰의 따라 다르게 발생하는 현상

코드는 예를 들어

c.list = rt.detaillst.Where(p => p.idx== c.idx  && p.SystemName.Trim() == "test").ToLiST()
평범하게 프로시져 받아온 데이타를 List 에 담았습니다.

그리고 이걸로  c.list.Count 를 갯수를 헤아렸습니다.

근데 0 이 나옵니다. 분명히 데이타가 있음에도 ;;;

진짜 원인도 모르겠고 원격지 서버라 디버깅도 안되고 하도 답답해서

	foreach (var r in rt.detaillst)
	{
	 _logger.LogInformation("00:" +r.idx.ToString() +"|" );
	}
부모 리스트 값을 LOG를 찍으니까 Count 값이 3으로 다시 나옵니다.

이게 말이 되는 상황인가 전체적인 코드나 환경을 공유할수 없지만

아니 관찰하지 않을때는 값이 없는데
Log로 관찰을 하니까 데이타 존재하는 현상

예전에는 이런 현상이 없는데 데이타가 커지면서 요근래 생겼습니다.
(10만개 정도)

예전부터 Linq 로 데이타 다룰떄 10만개가 넘으면 뭔가 이상작동을 했던 경험이 있어
Linq 에 대한 불신이 약간 있긴 한데 이번경우는 너무 황당하네요

당연히 제가 뭐 잘못해서 발생한 현상이고 이유는 있을것고 나중에
아 나 바보인가 하겠지만 지금은 그렇네요

2 Likes

정확히 기억은 안나지만 저도 이런 이중슬릿 현상을 겪은적이 있었는데
제 경우에는 다중 쓰레드 상황에서 그런 일이 벌어졌던걸로 기억합니다.

슈뢰딩거의 LinQ
제가 이래서 웬만하면 직접 만들어 씁니다.
원인이 밝혀지면 별 거 아닐 수도 있지만 숙련된 개발자도 헷갈릴 수 있다면 안 쓰는 게 낫다고 봐요

1 Like

그런데, Where 조건이 foreach에도 있어야 공평하지 않을까요?

슬릿과 슬립이 다른 것처럼, Where 조건의 여부는 차이가 큽니다. ^^

3 Likes

@kevin13 님이 말씀하신 것 처럼

원본 데이터의 유무랑 무관하게

작성하신 Where 절 조건에 부합하지 않아서

Count 값이 0 이 나오는거 아닐까요.

SomeType current = new(); // c
DataTable response = new(); // rt

int currentIndex = current.idx;
int sourceCount = response.detaillist.Count();
List<SomeType> testResults = response.detaillist
    .Where(row => row.idx == currentIndex)
    .Where(row => row.SystemName.Trim() == "test")
    .ToList();

int resultCount = testResults.Count();

_logger.LogInformation("Exected: {expected}, Actual: {actual}", sourceCount , resultCount );
3 Likes

where절 조건에 충족하는 item이 없을지도 모르겠군요

1 Like

윗 분들의 의견도 중요한 것 같고 제 의견은 Trim()이 걸립니다. 공백이 Trim()으로 제거되지 않았을 때 의도한 결과가 안나올 것 같거든요.

이 때 공백의 유무는 char.IsWhiteSpace()로 판단합니다.

4 Likes

네 저도 where condition 뭔가 다른값이 있는것 같습니다 trim 으로 제거 안되는
wt 라든가 오늘은 또 잘되는것 같네요

1 Like

별로 상관 없는 얘기일수도 있지만 카테고리가 F# Q&A로 되어 있네요.

1 Like

아 수정했습니다 ㅎ

1 Like

클릭 참기 힘든 제목…ㅎㅎ

2 Likes

rt.detaillst가 어떻게 만들어졌는지 알아야 원인을 추측해 볼 수 있지 않을까요?
foreach돌려서 잘 나온다는건 foreach돌리는 순간 rt.detaillst가 평가되었다는거고, 타이밍 이슈가 해소되었다고 보여져요. 위에 @fizzy 님 말씀 처럼요.
그리고 c.idx도 중요해 보입니다.

rt.detailst dapper에서 받아온 procedure 결과값입니다.
테이블 두개를 반환하면 1만개 10만개 레코드가 있었습니다.

가져온 값을 첫번쨰 테이블 키로 해서 두번째 테이블에서 데이타를
찾는 로직을 code상에서 처리했습니다.

1만개 키값으로 두번쨰 테이블 search 합니다. 처음에는 paller 병렬 처리로
돌리다가 아무래도 뭐가 이상한것 같아서 그냥 일반 순차 처리 했습니다.

아 뭔가 소스를 공유할만한 성격은 아닌것 같고 ;;
그냥 제착각이라고 생각하고 싶습니다 .
답변 달아주신분들 그냥 가십거리라고 생각해주시면 감사하겠습니다.^^

1 Like