我创建了一个允许通过namedpipes进行通信的Windows服务。
当我编写一些单元测试以启动管道并测试通信时,此代码工作正常,但现在我在Windows服务中安装了相同的代码,我收到以下错误:
Exception Info: System.IO.IOException
Stack:
at System.IO.__Error.WinIOError(Int32, System.String)
at System.IO.Pipes.NamedPipeServerStream.Create(System.String, System.IO.Pipes.PipeDirection, Int32, System.IO.Pipes.PipeTransmissionMode, System.IO.Pipes.PipeOptions, Int32, Int32, System.IO.Pipes.PipeAccessRights, SECURITY_ATTRIBUTES)
at System.IO.Pipes.NamedPipeServerStream..ctor(System.String, System.IO.Pipes.PipeDirection, Int32, System.IO.Pipes.PipeTransmissionMode, System.IO.Pipes.PipeOptions, Int32, Int32, System.IO.Pipes.PipeSecurity, System.IO.HandleInheritability, System.IO.Pipes.PipeAccessRights)
at System.IO.Pipes.NamedPipeServerStream..ctor(System.String, System.IO.Pipes.PipeDirection, Int32, System.IO.Pipes.PipeTransmissionMode,
System.IO.Pipes.PipeOptions, Int32, Int32, System.IO.Pipes.PipeSecurity)
at System.Threading.ThreadHelper.ThreadStart_Context(System.Object)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
at System.Threading.ThreadHelper.ThreadStart(System.Object)
现在我做了一些谷歌搜索,并在stackoverflow>中找到了这篇文章。 POST但我实现了这个(除了ps.AddAccessRule(pa);因为没有引用是pa是) 我得到了同样的错误。
这是我为该主题提供的代码:
var pipeSecurity = new PipeSecurity();
pipeSecurity.AddAccessRule(new PipeAccessRule("Users", PipeAccessRights.ReadWrite | PipeAccessRights.CreateNewInstance, AccessControlType.Allow));
pipeSecurity.AddAccessRule(new PipeAccessRule("CREATOR OWNER", PipeAccessRights.FullControl, AccessControlType.Allow));
pipeSecurity.AddAccessRule(new PipeAccessRule("SYSTEM", PipeAccessRights.FullControl, AccessControlType.Allow));
var pipeServer = new NamedPipeServerStream(pipeName, PipeDirection.InOut, numThreads, PipeTransmissionMode.Message, PipeOptions.Asynchronous, 1024, 1024, pipeSecurity);
pipeServer.WaitForConnection();
任何帮助都会很棒。
这里是运行监听器的代码:
Windows服务:
public static System.Timers.Timer Timer = new System.Timers.Timer();
public void Start()
{
Timer.Elapsed += (HeartBeat);
//Timer.Interval = 100; //Live
Timer.Interval = 2000; //Debug
Timer.Start();
}
public void Stop()
{
Timer.Stop();
}
private static void HeartBeat(object sender, ElapsedEventArgs e)
{
//listen for a message
ListenForMessage();
}
听众代码:
private const String pipeName = "StackOVerFlowPipeCode";
private const int numThreads = 10;
public static void ListenForMessage()
{
int i;
var servers = new Thread[numThreads];
for (i = 0; i < numThreads; i++)
{
servers[i] = new Thread(ServerThread);
servers[i].Start();
}
Thread.Sleep(250);
while (i > 0)
{
for (var j = 0; j < numThreads; j++)
{
if (servers[j] == null) continue;
if (!servers[j].Join(250)) continue;
servers[j] = null;
i--; // decrement the thread watch count
}
}
}
private static void ServerThread(object data)
{
try
{
var pipeServer = new NamedPipeServerStream(pipeName, PipeDirection.InOut, numThreads);
pipeServer.WaitForConnection();
var ss = new StreamString(pipeServer);
ss.WriteString(pipeName);
var message = ss.ReadString();
//DO STUFF HERE WITH MESSAGE
pipeServer.Close();
}
catch (Exception ex)
{
//CRY LIKE A BABY WHO LOST HIS TEDDY
throw ex;
}
}
发现异常消息:所有管道实例都忙。
答案 0 :(得分:2)
原来我的整个实现都有缺陷,我删除了很多代码并重写了它并且它有效。我从ListenForMessage()中删除了代码,并将其替换为ServerThread()中的代码,然后还将服务调用的方式更改为来自计时器的线程。它起作用了。
好吧,接收到消息后的代码(显示为//上面的Do Stuff)确实有效,但至少这个任务已经完成。
注意:永远不要只是复制和过去的代码并将其视为理所当然,请务必阅读并理解它。
答案 1 :(得分:1)
命名管道名称必须采用以下格式:
\\.\pipe\pipename
请参阅CreatedNamedPipe Win32 API:http://msdn.microsoft.com/en-us/library/aa365150(VS.85).aspx
编辑:在进一步检查(查看NamedPipeServerStream
样本)时,情况可能并非如此。因此需要查看异常的完整详细信息:Message
属性和运行时类型。
答案 2 :(得分:0)
您没有包含exception.Message但是根据NamedPipeServerStream的MSDN页面,IOException用于“已超出最大服务器实例数”。这是你得到的例外吗?
如果是这样,numThreads设置为什么,你可能有另一个app运行实例吗? (例如你正在试验的单元测试?)