Gis*_*shu 37 c# named-pipes .net-3.5
我启动了我的应用程序,它生成了许多Threads,每个Threads创建一个NamedPipeServer(.net 3.5为Named Pipe IPC添加了托管类型)并等待客户端连接(Blocks).代码按预期运行.
private void StartNamedPipeServer()
{
using (NamedPipeServerStream pipeStream =
new NamedPipeServerStream(m_sPipeName, PipeDirection.InOut, m_iMaxInstancesToCreate, PipeTransmissionMode.Message, PipeOptions.None))
{
m_pipeServers.Add(pipeStream);
while (!m_bShutdownRequested)
{
pipeStream.WaitForConnection();
Console.WriteLine("Client connection received by {0}", Thread.CurrentThread.Name);
....
Run Code Online (Sandbox Code Playgroud)
现在我还需要一种Shutdown方法来干净地完成这个过程.我尝试了通常的bool标志isShutdownRequested技巧.但是管道流在WaitForConnection()调用中保持阻塞,并且线程不会死亡.
public void Stop()
{
m_bShutdownRequested = true;
for (int i = 0; i < m_iMaxInstancesToCreate; i++)
{
Thread t = m_serverThreads[i];
NamedPipeServerStream pipeStream = m_pipeServers[i];
if (pipeStream != null)
{
if (pipeStream.IsConnected)
pipeStream.Disconnect();
pipeStream.Close();
pipeStream.Dispose();
}
Console.Write("Shutting down {0} ...", t.Name);
t.Join();
Console.WriteLine(" done!");
}
}
Run Code Online (Sandbox Code Playgroud)
加入永不回归.
我没有尝试但可能会工作的选项是调用Thread.Abort并吃掉异常.但它感觉不对..任何建议
更新2009-12-22
很抱歉没有提前发布..这是我收到的Kim Hamilton(BCL团队)的回复
执行可中断WaitForConnection的"正确"方法是调用BeginWaitForConnection,处理回调中的新连接,并关闭管道流以停止等待连接.如果管道关闭,EndWaitForConnection将抛出ObjectDisposedException,回调线程可以捕获它,清除任何松散的端点,并干净地退出.
我们意识到这必须是一个常见问题,因此我的团队中的某个人计划很快就此发表博客.
Jas*_*ver 38
这很俗气,但这是我开始工作的唯一方法.创建一个'假'客户端并连接到您的命名管道以移过WaitForConnection.每次都有效.
此外,甚至Thread.Abort()也没有为我解决这个问题.
_pipeserver.Dispose();
_pipeserver = null;
using (NamedPipeClientStream npcs = new NamedPipeClientStream("pipename"))
{
npcs.Connect(100);
}
Run Code Online (Sandbox Code Playgroud)
Ric*_*ard 14
切换到异步版本:BeginWaitForConnection.
如果它确实完成了,你需要一个标志,这样完成处理程序就可以调用EndWaitForConnection吸收任何异常并退出(调用End ...以确保能够清除任何资源).
小智 6
您可以使用以下扩展方法.请注意包含'ManualResetEvent cancelEvent' - 您可以从另一个线程设置此事件,以表示等待连接方法现在应该中止并关闭管道.设置m_bShutdownRequested时包含cancelEvent.Set(),关闭应该相对优雅.
public static void WaitForConnectionEx(this NamedPipeServerStream stream, ManualResetEvent cancelEvent)
{
Exception e = null;
AutoResetEvent connectEvent = new AutoResetEvent(false);
stream.BeginWaitForConnection(ar =>
{
try
{
stream.EndWaitForConnection(ar);
}
catch (Exception er)
{
e = er;
}
connectEvent.Set();
}, null);
if (WaitHandle.WaitAny(new WaitHandle[] { connectEvent, cancelEvent }) == 1)
stream.Close();
if (e != null)
throw e; // rethrow exception
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
18607 次 |
| 最近记录: |