Điều bạn có thể phải làm là đọc và viết không đồng bộ với NamedPipeClientStream.BeginRead
và NamedPipeClientStream.BeginWrite
; một bộ đếm thời gian sẽ được sử dụng để phát hiện khi dữ liệu chưa được gửi hoặc nhận trong một khoảng thời gian.
Bất cứ khi nào dữ liệu được gửi hoặc nhận, trường DateTime
sẽ được đặt thành DateTime.Now
và mỗi lần thực hiện bộ hẹn giờ sẽ kiểm tra trường đó để xác định xem thời gian chờ có xảy ra hay không. Nếu xảy ra, NamedPipeClientStream
có thể bị đóng và các trường hợp ngoại lệ từ NamedPipeClientStream.EndRead
và NamedPipeClientStream.EndWrite
có thể bị phát hiện.
Tôi chưa có ví dụ làm việc, nhưng tôi sẽ làm việc trên một ví dụ nếu bạn cần. Hy vọng rằng điều này sẽ giúp bạn ra ngoài trong thời gian có ý nghĩa.
Đây là một số mã ví dụ rất thô. Sẽ cần nhiều hơn nữa, chẳng hạn như thực hiện IDisposable
và thêm phương thức ghi. Điều này sẽ giúp minh họa ý tưởng, mặc dù. Nó có lẽ sẽ tốt nhất để sử dụng mã này như là một mô hình, thay vì sử dụng nó trực tiếp. Tôi đã kiểm tra mã để xem nó có đọc hay không.
//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;
}
}
Bạn đang cố gắng sử dụng Ống có tên thẳng hoặc bạn đang xem sử dụng WCF trên Ống có tên? –
@AdamGritt: ống thẳng có tên. –