견고한 타임 아웃 관리로 명명 된 파이프 IPC를 구현하는 가장 좋은 방법을 찾는 데 어려움을 겪고 있습니다. 연결 설정시 시간 초과를 의미하지는 않지만 읽기/쓰기 스트림에서 시간 초과를 의미합니다.예제 파이프 이름 읽기/쓰기 타임 아웃이있는 IPC
내가 발견 한 모든 예제에는 시간 초과 구현이 없습니다.
누군가가 내게 실제적인 예를 보여줄 수 있습니까? 그리고/또는 이것을 보여주는 예를 보여줄 수 있습니까?
견고한 타임 아웃 관리로 명명 된 파이프 IPC를 구현하는 가장 좋은 방법을 찾는 데 어려움을 겪고 있습니다. 연결 설정시 시간 초과를 의미하지는 않지만 읽기/쓰기 스트림에서 시간 초과를 의미합니다.예제 파이프 이름 읽기/쓰기 타임 아웃이있는 IPC
내가 발견 한 모든 예제에는 시간 초과 구현이 없습니다.
누군가가 내게 실제적인 예를 보여줄 수 있습니까? 그리고/또는 이것을 보여주는 예를 보여줄 수 있습니까?
비동기 읽기 및 쓰기는 NamedPipeClientStream.BeginRead
및 NamedPipeClientStream.BeginWrite
으로 수행해야합니다. 일정 시간 동안 데이터가 보내지거나 수신되지 않았을 때 타이머가 감지됩니다.
데이터가 전송되거나 수신 될 때마다 DateTime
필드는 DateTime.Now
으로 설정되고 타이머를 실행할 때마다 해당 필드가 시간 초과가 발생하는지 확인합니다. 하나가 발생하면 NamedPipeClientStream
을 닫을 수 있으며 NamedPipeClientStream.EndRead
및 NamedPipeClientStream.EndWrite
의 예외가 잡힐 수 있습니다.
실습 예제가 아직 준비되지 않았지만 필요에 따라 작업하겠습니다. 바라기를 이것은 뜻있는 시간에 당신을 도울 것입니다.
이것은 매우 거친 예제 코드입니다. IDisposable
을 구현하고 쓰기 메소드를 추가하는 등 더 많은 작업을 수행해야합니다. 그래도 아이디어를 설명하는 데 도움이됩니다. 아마도이 코드를 직접 사용하는 대신 모델로 사용하는 것이 가장 좋습니다. 코드를 테스트하여 읽었는지 확인합니다.
//this is a very rough model of how to do it. a lot more would need to be implemented
//i'm assuming you plan to continuously read from it. i can think up another example if you're not
//also not thread safe
public class MyPipeClient
{
NamedPipeClientStream PipeClient = new NamedPipeClientStream("testpipe1");
Timer TimeoutTimer;
DateTime LastRead;
const int TimeoutSeconds = 120; //2 mins
//will connect and start receiving
public void Connect()
{
PipeClient.Connect();
LastRead = DateTime.Now;
TimeoutTimer = new Timer(TimeoutCheck, this, 0, 1000); //check every second
Read(this);
}
public void Disconnect()
{
PipeClient.Close(); PipeClient = null;
TimeoutTimer.Dispose(); TimeoutTimer = null;
}
static void Read(MyPipeClient client)
{
PipeState state = new PipeState(client);
try
{
client.PipeClient.BeginRead(state.Buffer, 0, state.Buffer.Length, ReadCallback, state);
}
catch (InvalidOperationException) //disconnected/disposed
{
return;
}
}
static void ReadCallback(IAsyncResult ar)
{
PipeState state = (PipeState)ar.AsyncState;
MyPipeClient client = state.Client;
client.LastRead = DateTime.Now;
int bytesRead;
try
{
bytesRead = client.PipeClient.EndRead(ar);
}
catch (IOException) //closed
{
return;
}
if (bytesRead > 0)
{
byte[] data = state.Buffer;
//TODO: something
}
else //i've never used pipes, so i'm assuming this behavior exists with them
{
client.Disconnect();
return;
}
Read(client);
}
static void TimeoutCheck(object state)
{
MyPipeClient client = (MyPipeClient)state;
TimeSpan timeSinceLastRead = DateTime.Now - client.LastRead;
if (timeSinceLastRead.TotalSeconds > TimeoutSeconds)
{
client.Disconnect();
}
}
}
class PipeState
{
public byte[] Buffer = new byte[4096];
public MyPipeClient Client;
public PipeState(MyPipeClient client)
{
Client = client;
}
}
그레이트보기; 나는 이것을 시도 할 것이다. –
스트레이트 된 명명 된 파이프를 사용하려고합니까? 아니면 명명 된 파이프를 통해 WCF를 사용하고 있습니까? –
@AdamGritt : 직선 명명 된 파이프. –