I have another question about this same code and keeping the pipe open after the client closes it
但是我在优雅地终止我的应用程序时遇到了问题。我的主要代码如下。有两个问题。 1)我正在使用Thread.Abort和2)这个应用程序实际上并没有结束。我可以设置一个断点并看到中止被调用并逐步到结束括号,但IDE仍处于调试模式,并且该进程仍处于活动状态(在进程管理器中)。我如何正确终止这个?
[STAThread]
static void Main(string[] args)
{
Thread t;
t = new Thread(new ThreadStart(ThreadStartServer));
bool hasInstance = true;
try
{
pipeStream = new NamedPipeServerStream(pipename);
hasInstance = false;
pipeStream.Close();
t.Start();
pipeStream.Dispose();
}
catch (System.IO.IOException)
{
hasInstance = true;
}
if (hasInstance)
{
clientPipeMessage(args[1]);
return;
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
t.Abort();
}
static public void ThreadStartServer()
{
while (true)
{
using (NamedPipeServerStream pipeStream = new NamedPipeServerStream(pipename))
{
Console.WriteLine("[Server] Pipe created {0}", pipeStream.GetHashCode());
// Wait for a connection
pipeStream.WaitForConnection();
Console.WriteLine("[Server] Pipe connection established");
using (StreamReader sr = new StreamReader(pipeStream))
{
string temp;
while ((temp = sr.ReadLine()) != null)
{
Console.WriteLine("{0}: {1}", DateTime.Now, temp);
}
}
}
}
Console.WriteLine("Connection lost");
}
答案 0 :(得分:2)
关于来自MS文档的Thread.Abort ......“调用此方法通常会终止该线程。” 此外,“线程不能保证立即中止,或根本不会中止。”
我怀疑WaitForConnection阻止它接收线程中止。一般来说,线程中止被认为是邪恶,因为谁知道你可以留下什么状态,等等。请参阅这里以获得更多帮助...... http://www.interact-sw.co.uk/iangblog/2004/11/12/cancellation
答案 1 :(得分:0)
如你所知......不要使用Thread.Abort。除非你有一个非常令人信服的理由,为什么没有其他选择可行,这是一个坏主意。
问题是阻塞调用ReadLine ...所以改为使用StreamReader.Peek / Read从命名管道中提取数据。这将允许您检查循环中的标志,以便您可以退出。
对于更复杂的解决方案,您可以使用异步I / O ...有关指示,请参阅此question。
答案 2 :(得分:0)
完成其工作后,您需要从ThreadStartServer方法“返回”。如果将它与Main方法中的Join()结合使用,则工作线程将正常完成。另外使它成为BackGround线程。这是一个例子(没有PipeStream):
class Prog
{
static void Main(string[] args)
{
Thread t;
t = new Thread(new ThreadStart(ThreadStartServer));
t.IsBackground = true;
try
{
t.Start();
// time consuming work here
}
catch (System.IO.IOException)
{
// from your example
}
t.Join();
}
static public void ThreadStartServer()
{
while (true)
{
int counter=0;
while (++counter < 10)
{
Console.WriteLine("working.");
// do time consuming things
Thread.Sleep(500);
}
return;
}
}
}