저는 .NET C#에서 TCP 서버를 개발 중입니다. 비동기 I/O (I/O 완료)를 사용하여 많은 수의 클라이언트를 동시에 처리합니다. 지금은 목록에 모든 TCP 연결이 있습니다.이 연결은 특정 연결의 상태 시스템에서 지속적으로 변경을 검색합니다. 지정된 연결에 대한 상태 시스템은 I/O 완료가 특정 플래그를 설정하면 업데이트됩니다.C# .NET Server 다중 연결 폴링 - 더 좋은 방법이 있습니까?
이 작업을 수행하는 더 좋은 방법이 있다고 확신합니다. 현재 업데이트는 업데이트를 기다리는 것을 차단하지 않고 조절을 사용하지 않고 폴링하므로 프로세서 집약적입니다. 내 서버가 사이클을 낭비하고 있는지 신경 쓰지 않지만 가난한 디자인이라고 생각합니다. I/O 완료 신호가 처리해야 할 부분이있을 때만 특정 연결을 처리하는 방법을 찾고, 그렇지 않을 경우 대기 (즉, 휴면)합니다. 아무도 좋은 방법을 제안 할 수 있습니까?
일부 스레드 동기화 작업은 루핑중인 주 스레드에서 I/O 완료가 완료 될 때까지 기다릴 수 있다고 생각했습니다. 그러나 I/O 완료는 호출 스레드 (데이터를 즉시 사용할 수있는 경우 등)를 사용하여 실행되는 경우가 있으므로이 솔루션에서 문제를 일으킬 수 있습니다.
당신이 제안 할 수있는 것은 무엇이든 주시면 감사하겠습니다!
//Do communications on each client we currently have connected.
//This loops runs backwards so we can delete elements on the fly
//without have to iterate through more than once.
lock (rgClient)
{
for (i = rgClient.Count - 1; i >= 0; i--)
{
if (!rgClient[i].DoComm())
{
rgClient[i].DoClose();
rgClient.RemoveAt(i);
}
}
}
DoComm() 연결에 대한 상태 머신의 업데이트를 수행하고, 수반 : 여기
메인 쓰레드에 의해 실행된다 (간략화 된) 루프 (rgClient 클라이언트의리스트 임) 현재 상태의 활동을 실행 한 다음 필요한 경우 새 상태로 전환합니다.class StateAck : State
{
public StateAck(TextBox txtOutputExt, Form fmOwner)
: base(txtOutputExt, fmOwner)
{
fWriting = false;
}
public override bool DoExecute(out Type tpNextState)
{
PktAck pkt;
if (!base.DoExecute(out tpNextState))
{
return false;
}
//Start a write if we haven't yet
if (!fWriting)
{
pkt = new PktAck();
fWriting = true;
return FPutPkt(pkt.rgbSerialize());
}
//Is the read finished/has an error occurred?
if (fDataErrorWrite)
{
return false;
}
//Process the data
if (fDataWritten)
{
tpNextState = typeof(StateIdle);
}
return true;
}
private bool fWriting;
}
실행이 DoExecute 통과()마다 DoComm() 메인 스레드에서 호출 : 다음은 간단한 "ACK"패킷을 전송하는 상태 클래스입니다. 99 %의 시간, 실제로는 아무 것도 발생하지 않습니다. FPutPkt()를 호출하여 시작된 쓰기가 완료되면 플래그가이를 알리고 다음 상태가 "유휴"로 설정됩니다. 내가하고 싶은 일은 메인 스레드가 네트워크 활동을 끝내고 DoExecute()를 통해 상수 및 중복 전달을 피하기 위해 업데이트가 필요한 클라이언트 만 검사하는 것입니다.
나는 코드를 보여줄 것을 제안합니다. 이렇게하면 토론의 기반이됩니다. –
그리고 왜 I/O 완료 루틴이이를 처리 할 수 없습니까? I/O 완료를 사용하는 것이 전부 아닌가? –
이 기사를 확인할 수 있습니다. http://www.codeproject.com/KB/IP/dotnettcp.aspx – Iraklis