invoke를 해도 종종 에러가 뜸; ㅠ.ㅠ
밀도장을 계산하고, 노말라이즈 해서 픽셀 정보로 바꿈
바꾼 픽셀은 map이라는 bitmap 객체에 저장되고, 한 세트를 다 그리면 picturebox1.image에 넣어서 표시함
여기까진 상관 없는데
표시한 뒤에 map을 Save 메소드로 저장할려고 하니까 어디선가 쓰고 있다면서 지랄발광을 함 -_-
그래서 map.Save() 메소드를 불러오는 함수를 따로 만들고 델리게이트로 연산하는 쓰레드에 invoke 한 상황인데
여전히 계산중에 폼을 클릭하면 쓰레드 문제가 발생함...
Lock() 은 쓰는 방법을 몰라서 -_- 인터넷에서 검색한 방법대로 해도 해결 못해서 invoke를 사용한 상황
원하는 해결책은 두가지
1. 쓰레드에 안전한 image - file 저장 방법 Save 메소드 말고 ..
2. 쓰레드에 안전하게 뮤텍스를 쓰는 제대로된 방법
ㅠ.ㅠ
Save 메소드 쓰는 줄을 락으로 감쌌는데 이건 아예 해결이 안되던데 ㅠ.ㅠ
뭔가 원인이 있어서 일듯한데..딱히 원인이 떠오르지 않네
핫산 왜 스레드를 썼는가
핫산 왜 디버깅을 하지 않는가
UI 를 건드리는 쓰레드는 단 하나여야돼. thread safe 하지 않아.
안씁미다 ..
어떻게 해야됩니까 ㅠ.ㅠ
만약 단 하나의 thread 에 의해 UI가 갱신될때 data 를 Read Only 로 접근한다면 문제가 없어야해.
picturebox1 에 넘기기 전에 map 을 다른 메모리 객체에 복사해 뒀다가 그걸 저장하면 당연히 문제는 없겠지?
UI가 picturebox1을 갱신하고 있고, thread1이 데이터를 bitmap으로 만들어서 picturebox1로 넘겨주고 있습니닷... 여기까진 문제없이 되는데 thread1의 bitmap을 Save로 저장할때 쓰레드 에러가 ...
한번 트라이해보겠습니당
물론 하나의 데이타로도 문제가 없어야 되는데 내가보기엔 C#이 기본적으로 여러 쓰레드에 의해 운용되고 있기 때문에 발생하는 문제일거야. GC를 포함해서 말야.
그렇게 하니까 invoke 없이도 Save가 안전하게 되는데 여전히 form1의 위치를 옮기려고 마우스로 드래그 하면 에러가 발생합니다.
ㅋㅋ UI 단이 꼬여있구만~
picturebox1 으로 넘겨주는 부분만 막아놓고 처리하면 어때? 그런식으로 문제를 일으키는 녀석을 추적해봐.
하나씩 리마크해서 말야.
역시 Save() 이 메소드가 문제인거 같습니당 .. 점마 주석처리하고 UI 휘휘 돌려도 멀쩡하네여 ㅠ.ㅠ thread-safe하지 않다고 하던데 해결 방법으로 제시한 Lock을 써도 안되는게 문제 .. Lock이나 뮤텍스를 좀더 공부해야봐야할듯 합니다 ㅠ.ㅠ
나도 첨에는 그거 생각했는데 그 문제 아닐거같아. 저장하는거랑 ui랑 상관없을듯
마우스 드래그나 창위치 변경 이벤트때 뭔가 건드린다 90%
이야기가 점점 내가 감당할 수 없는 방향으로 흘러가는 느낌;;; 프로그래밍 진짜 존나 개복잡함 ㅠ.ㅠ
또는, save하고 나서 draw 하는 행위 자체가 문제거나(창위치 움직이면서 draw 다시 하겠죠 뭐)
save 하고나서 창 최소화 했다가 다시 열어보시죠
아닝 아무리 코드가 복잡해도 문제를 일으키는 원인은 줄여나갈 수 있어.
에러 남
좁혀나갈 수 있어 : )
데이타를 UI 에 전달해주지 않고 저장만 해도 UI 를 움직이면 에러가 난다는게 좀 우습지 않아?
간단히 생각해봐.
draw 하는 부분을 브레이크 걸고 디버깅 해보세여
니가 그냥 저장하는 기능을 만들었어. UI랑 별도로 말야. 그 앱이 오류가 날까?
핫산 왜 디버깅을 하지 않았는가
picturebox1에 데이터 안넘겨주면 Save해도 에러 안나는데 지금 이 말은 Save가 아니라 데이터 넘겨주는 친구를 invoke 해야된다는 의미져?
임계구역에 여럿이 동시 접근안하게 막아주면 되죠 뭐
그런데 다중스레드 동시접근으로 인한거 맞아요? save 자체에 문제 없듬?
Save이거 제가 만든거 아니에여 c#내장 메소드임 thread-safe하지 않다고 알려져있음
다중스레드 동시접근 얘긴 무슨 소린지 모르겠음 ... Form 돌리는 쓰레드는 원래 있을거고 ..
자 이제 picturebox1 에 넘겨준 상태에서 GUI 에서 해당 데이타에 접근할걸로 보이는 모든 메서드를 주석처리하고 하나씩 풀어봐.
특히 OnDraw 같은 식의 메서드들.
pictureBox1.Image = map; 이게 gui에 그릴때 제가 쓴 유일한 코드인데 ...
draw 가 아니라 대입?
넵 저렇게만 해도 form1에 있는 picturebox1에 갱신이 되더라구요
WinForm에서 저정도로 Thread 에러나면 WPF로 개발하면 장난아니겠다... ㅋㅋㅋ
심지어 form 박스 크기 줄여서 picturebox1 가렸다가 다시 키우면 또 에러뜸 ㅋㅋㅋ
니가 하나만 생성해서 여기저기 레퍼런스만 복사하고 있다는 느낌이 든다 ㅡㅡㅋ
당장은 혼자 만들어서 쓸거라 감수하고 쓰면 되겠지만 만약 배포한다고치면 이대로는;;
내가 사실 의심되는것은 c# 내부 메모리 관리쪽인데, 내가 한번 격어봐서 고생했거든.. GC가 안되는 경우가 있었거든.. 그래도 UI Thread 랑은 무관함
기본적으로 개념이 없으시네유~
c#도 그거 지정해줄 수 있습니까? 항상 그게 의문이었음요 .. 이게 데이터를 복사하는건지 레퍼런스를 옮기는건지
아티클 읽어보니 누군가가 PaintBox 쓰지 말고 직접 Form 위에 그리는게 젤 빠르다네.
아 ...
기본 예제를 충분히 검색해보시웅. 뭐 코드가 복잡하고의 문제가 아닌듯 : )
GC 문제가 아니기만 ㅠ.ㅠ 이건 아예 노답인거니..
그거랑 상관없어 ㅋㅋ
답변감사합니당 일단 쓰레드 공부하는거보단 폼에 직접 그리는걸로 해봐야겠습니당
비트맵을 PaintBox의 width height 크기로 생성했을테니 그게 리사이징 되면 웃겨지는거지.
만약 리사이징될때마다 재생성하면 어떻겠어. 개그지.
그런데 저장은 제대로 되나여
넹 저장은 다른 비트맵 객체 만들어서 저장하는걸로 하니까 invoke 없이도 에러 안나고 잘되네요
그게 Bitmap 해제시 레퍼런스가 남아서 해제가 안되는거 였는데.. 여튼 그래도 UI Thread랑은 전혀 무관해야할거같음. 아니면 winform 구조를 몰라서 그러는데 주기적으로 화면 갱신하는거 아님? 갱신할려고 bitmap 참조하는데, save하겟다고 lock 걸어서 에러 나는거 아닌가?
저장하면 난리친다잖아영~
아 다른 맵에 복사하곤 잘된데영~ 당연히 잘되어야지.
이렇게되면 별도의 Thread에서 UI Thread 참조하게되는거니.. 에러가 날수있겠지.. 근데 save 내부구조를 모르니 그냥 상상 ㅋㅋ
코세야..너 30분에 할일있자너..얼렁 가라.. ㅋ
이번에 객체 옮겨서 할 땐 Lock이나 mutex, invoke 아무 것도 없이 할때 문제 없던거 봐선 form에서 해당 bitmap 참조하려다 생기는 에러는 아닌듯 싶습니다.
17분 남았다.
또 미루는거봐라.. ㅋㅋ 얼렁가서 미리 대기하고 있어라
바부 lock 이랑 상관없어 원래.
paintbox 에서 해당 map 건드리는 바람에 나는 에러가 맞다고 봄.
보통 draw 요청은 가려진부분이 다시 보일때만요
폼을 리사이징 하면 paintbox 의 맵은 어떻게될지 생각해보시우~
9분남았네.. 얼렁가라 ㅋㅋ 난 일할란다..오늘은 꼭 마무리해야지..
응~
14분 남았는데 니 시계 이상함.