저는 C#에서 멀티 스레드 프로젝트를 진행하고 있습니다. 작업자 스레드를 제어하기위한 아이디어는 기대만큼 쉽게 작동하지 않습니다.C#의 스레드 동기화 (모니터 대기/펄스 사용)
메인 GUI 윈도우가 시작될 때 스레드가 생성되고, 여기가 실행되는 기능입니다 : 버튼이 GUI를 클릭하면
private void continueReading()
{
while (true)
{
lock (_lock)
{
while (!startDAQ)
Monitor.Wait(_lock);
startDAQ = false;
logging = true;
daqTaskComponent1.ReadAsync();
}
}
}
는 지금, startDAQ true로 설정하고, _lock한다 ReadAsync()를 호출하는 스레드를 시작하기 위해 펄스가 울립니다.
Async의 콜백 함수에서 동일한 _lock 객체를 잠그고 계산을 수행 한 다음 startDAQ를 true로 설정하고 다시 펄스합니다.
이렇게하면 콜백이 더 많은 데이터를 처리 할 준비가되었을 때만 Async 기능을 호출 할 수 있습니다.
문제는 continueReading 스레드가 Monitor.Wait에서 일시 중지되도록하고 일시 중지하기 전에 ReadAsync가 호출 된 경우 콜백을 허용함으로써 데이터 수집을 안전하게 일시 중지 할 수 있어야합니다. 이 제대로 작동되지 않고
lock (_lock)
{
startDAQ = false;
Monitor.PulseAll(_lock);
while (logging)
Monitor.Wait(_lock);
}
좀 교착 상태를 받고 있어요 :
이
은 사용자가 데이터 수집을 일시 중지 버튼을 다시 클릭 할 때 내가 실행 해요 코드입니다. 이것은 모니터와 대기/펄스를 사용하여 스레드간에 신호를 보내는 첫 번째 시간이기 때문에 약간 어려움을 겪었으며이를 처리하는 더 쉬운 방법이 있다는 느낌이 들었습니다. 어떤 도움이나 제안을 주시면 감사하겠습니다.편집 : 다음은 콜백 함수에서 관련 코드 :
lock (_lock)
{
//Lots of code here that just manipulates the data passed to the callback
startDAQ = true;
logging = false;
Monitor.PulseAll(_lock);
}
추가 내가 원래 내 코드를 붙여 넣을 때 깜빡 로깅 부울.
문제가 무엇인지 설명하십시오. 적절하게 잘못된 해결 방법을 얻으려고하면 엉망이 될 수 있습니다. – PVitt
문제는 현재 코드에서 교착 상태가 발생한다는 것입니다. 루프를 실행하는 스레드가 어떻게 안전하게 멈출 수 있는지 잘 모르겠습니다. 사용자가 버튼을 클릭하여 ReadAsync를 호출하는 스레드를 시작하고 중지 할 수있게하려고합니다. 사용자가 스레드를 중지하면 콜백 함수에 문제를 일으킬 일부 정리를 수행해야하는데, 이는 정리 대기가 발생하기 전에 보류중인 ReadAsync가 완료되어야하는 이유입니다. – Shaun
startDAQ는 * volatile *로 선언해야합니다. –