2012-08-09 2 views
2

C#으로 작성된 라이브러리를 사용하는 C++/CLI로 작성된 응용 프로그램이 있습니다. 이 응용 프로그램은 표준 소켓 API를 사용하여 작성되었으며 select()를 사용하여 일반적인 비 비동기 소켓을 다중화합니다. 그러나 타사 라이브러리는 .NET 소켓을 사용하고 비동기 결과 및 콜백을 사용합니다.select()를 사용하는 비동기 .NET 소켓 및 표준 소켓 : select()가 비동기 콜백을 방지하는 이유는 무엇입니까?

다음은 시나리오입니다. 메인 스레드 (주로 네이티브 스타일 코드를 사용하는 C++/CLI 응용 프로그램)에 일반 소켓을 만듭니다. 제 3 자 라이브러리 공급 업체의 C# "session"객체를 만듭니다.이 객체는 내부적으로 .NET 클래스의 비동기 소켓이 있습니다.

내가 알아챈 점은 C# "세션"개체를 인스턴스화하는 주 스레드의 select()에 NULL 시간 제한 매개 변수를 넣으면 해당 .NET 소켓에 대해 비동기 콜백이 수행되지 않는다는 것입니다. 1 초의 타임 아웃을 사용하고 비동기 소켓에서 다른 활동이 발생하지 않으면 select()가 시간 초과 될 때까지 비동기 소켓 콜백이 전달되지 않습니다.

아무튼 select()가 .NET 소켓에 콜백을하지 못하게합니다. 어떻게 이것을 피할 수 있습니까? .NET 소켓에 비동기 콜백을 전달할 수있는 이전 소켓에 사용할 수있는 대체 폴링 메서드가 있습니까?

+0

콜백이 동일한 스레드에서 발생한다고 상상해보십시오. Select()가 해당 스레드를 차단하면 실행 루프에서 다른 것을 처리 할 수 ​​없습니다. –

+0

내가 혼란스러워하는 부분은 select()에 대한 MSDN 도움말이 차단 될 때 경고 대기 상태임을 나타냅니다. .NET 비동기 콜백은 "경고"를 발생시키는 것으로 간주되지 않습니까? –

+0

나는 모든 .Net 콜백이 Application.DoEvents()에서 처리된다고 생각한다. http://msdn.microsoft.com/en-us/library/system.windows.forms.application.doevents.aspx –

답변

0

해결책을 찾았습니다.

.NET에서 사용되는 AsyncCallbacks는 send()/recv() 함수를 포함하여 블록하지 않는 함수를 사용할 수 없습니다. [적어도] .) AsyncCallback에서 블로킹 함수가 호출되면 비헤이비어가 정의되지 않습니다. 코드에서이 "undefinedness"를 제거하고 나면 모든 것이 정상적으로 작동하기 시작합니다.

WaitForMultipleObjectsEx()에 대한 select()를 바꾼 AsyncCallback에 멀티플렉싱을 트리거하여이 문제를 해결 한 정책 클래스를 작성하여 클래스를 다시 템플릿 화했습니다. 이것은 대부분의 문제를 해결하는 것처럼 보였습니다.

[1] 편집 : 아래 코멘트를 참조하십시오. 비 차단 또는 블로킹 소켓에서 send()를 사용했는지 여부는 "깨는 점"과 정의되지 않은 동작에 차이가있는 것 같지 않았습니다.

+0

아, 내가 말하고자했던 것은 send()/recv()를 non-blocking으로 만들고 비동기 콜백에서 사용하면 여전히 "카운트"한다는 것입니다. 비동기 콜백의 비 블로킹 소켓에서 send()를 제거하면 모든 작업이 시작됩니다. send()에서 사용 된 소켓의 blocking/non-blocking 상태를 바꾸는 것은 효과가없는 것 같습니다. 위의 응답을 수정했습니다. –