• 카테고리

    질문 & 답변
  • 세부 분야

    웹 개발

  • 해결 여부

    해결됨

재질문

22.10.06 12:47 작성 조회수 150

1

어제 질문드렸는데 navigationmanager로 해결이 안되어 다시 질문 남깁니다

현재 저는 stream형식으로 데이터를 받아오는 코드를 구현하고 있고 이를 업데이트하기 위해 await InvokeAsync(StateHasChanged); 라는 코드를 사용하고 있습니다.

평상시에는 StateHasChanged가 잘 동작하기에 생명주기 함수에만 넣어야하는 함수는 아닌 것 같습니다..

오직 문제는 다른 페이지로 전환했다 돌아왔을 시 StateHasChanged가 동작하지 않습니다. (디버깅으로 확인한 결과 평소에는 StateHasChanged 이후에 html 코드쪽으로 가서 업데이트 작업이 진행되는데 문제의 경우에는 html로 가지않고 바로 넘어가버림)
(수정된 내용을 찾지 못하는걸까요??)

데이터는 정상적으로 들어간게 디버깅을 통해서도 확인되었고 또 이벤트 (아무런 기능없는 버튼 클릭, 다시 다른페이지로 이동했다 돌아옴) 가 발생하면 정상적으로 모든 데이터가 출력됩니다.

오직 다른페이지로 넘어갔다 돌아왔을 시 "실시간으로 업데이트해주는 기능" 만 동작을 멈춤니다.

검색한 바로는 비동기 활용 시 쓰레드가 달라져 싱크가 안맞는 문제가 있는거같기도한데...(SynchronizationContext, ExecutionContext)
제 생각에는 이게 가장 그럴듯해 보이더라구요 async 사용하면서 쓰레드가 달라져서 StateHasChanged()가 변경된 부분을 인식 못한다는게 맞을까요?

버튼을 누르는 것과 StateHasChanged 를 호출하는 것 둘 사이에 무슨 차이점이 있길래 하나만 동작하는걸까요

 

Blazor (Client-side) StateHasChanged() not updating page - coder-solution-es.com

해당 주소의 방법으로 임시적으로 돌아가게는 구현했습니다.

아무것도 없는 refresh 페이지를 만들고 init에서 바로 NavigateTo를 활용해 원하는 주소로 돌아가게 구현하는 방식입니다. 이렇게 하면 페이지가 전환되더라도 실시간으로 업데이트가 됩니다...

하지만 매번 반복문마다 저 NavigateTo를 하는건 아무리 봐도 해당 방법은 쓸데없는 동작이 많아( 깜빡임도 발생합니다) 임시 방편으로만 쓸만한거같은데 혹시 저 임시방편 해결책을 통해 저의 근본적인 문제가 무었인지 알 수 있을까요...?

 

 

최대한 자세히 제 상황을 알려드리려 하다보니 질문이 길어져서 죄송합니다...

 

 

 

답변 1

답변을 작성해보세요.

0

저도 이해하기 어려운 상황에 놓이신 것 같네요. 처음에는 어떤 말씀이었는지 잘못 해석했었고 StateHasChanged도 다른 곳에서도 작동한다는 점을 머릿속에서 수정했습니다.

 

그렇지만 정확히 어떤 타이밍에 문제가 생기는 지를 알아낸 것 같습니다. 밑의 예시가 도움이 되실 것으로 보입니다. 예를 들어 인덱스 페이지에 타이머를 만들고 카운터에 갔다가 다시 돌아왔을 때를 예시로 들어보겠습니다. 이 코드는 https://learn.microsoft.com/ko-kr/aspnet/core/blazor/components/lifecycle?view=aspnetcore-6.0 에도 있습니다.

imageimage

디스포스가 있을 경우 :

image

사진에서 보시는 것 처럼 11 이후 카운테 페이지로 이동하면 멈추었다가 다시 1부터 세기 시작하고 웹의 표시도 그에 맞추어 따라가고 있습니다.

디스포스가 없을 경우 :

image

4번 이후 카운터로 넘어가도 타이머가 실행되고 다시 해당 페이지에 돌아 왔을 때 1번 타이머와 2번 타이머가 동시에 흘러가는 것을 볼 수 가 있습니다. 웹 페이지에는 2번 타이머의 값이 출력되고 있습니다.

 

영상을 업로드 할 수 있었으면 좋았을 텐데 그러지 못해 사진으로 대체 했습니다. 위에서 설명드린대로 다른 페이지로 넘어갔을 때 새 작업에 기존 작업이 묻혀서 웹 페이지에 제대로 표시가 되지 않은 걸까? 라고 추측해 보았습니다.

디스포스를 적절하게 추가시켜서 작업을 해보시고 그럼에도 같은 문제가 발생한다면..... 해결하기가 어렵지 않을 까 생각됩ㄴ디ㅏ.

감사합니다. 저는 instance를 생성해서 그 안에 데이터를 삽입했기에 조금 다른 것 같지만 이론적인 부분을 이해하는데 많은 도움이 되었습니다. 결국 Action을 활용해 특정 함수를 등록해주고 해지해주는 방식으로 해결하였습니다.

올려주신 답변을 보니 살짝 궁금한 부분이 생겼습니다.

이전 질문에서도 살짝 언급했는데 제가 이해하기로는 페이지 전환 시 해당 페이지 에서(@code 부분) 선언한 변수들은 초기화가 되지만 종속성 주입을 통해 instance를 생성하면 그 내부의 데이터는 사라지지 않기에 페이지 전환 후에도 값을 유지하고싶으면 이러한 방법을 사용한다는 것이 맞는 이해일까요?

 

그렇다면 위에서 Timer가 일반변수들과 다르게 페이지를 전환하더라도 사라지지 않는건 timer 의 특수성으로인해 사라지지 않고 유지되는 특성이 있는건가요?

타이머가 특수한 경우이라기 보다는 위에서 사용한 Invokeasync로 인해 자바스크립트로 따로 작동이 빼져서 그런 것 같습니다.

네, 종속성 주입이 그런 용도로 주로 사용되는 것 같습니다.

실제로 여러 문서에서도 dispose를 왠만해서는 구현해놓으라고 되어있기에 다음부터는 이것을 감안하고 프로그래밍 하시는것이 좋을 것 같습니다.

아 네 감사합니다!

직접학습하려니 어렵고 헷갈리는 부분들이 많이 나오는데... 친절하게 알려주셔서 그런부분들이 정리가 조금 된 것 같습니다!

빠르고 친절한 답변 항상 감사드립니다.