Многопоточность NamePipeServer в С#
Привет
Я хочу использовать NamedPipeServerStream, который является новым из .NET 3.5 для обмена сообщениями namedpipe.
Я хочу написать многопоточный сервер трубопроводов. это обрабатывается по умолчанию, или я должен написать для этого код. мой сервер труб должен обрабатывать несколько запросов за раз
любое решение или код?
Ответы
Ответ 1
Каждый экземпляр NamedPipeServerStream представляет собой реализацию Stream, переносящую дескриптор в экземпляр именованного канала. Вы можете (и сервер с многопоточным каналом) иметь несколько экземпляров NamedPipeServerStream для одного и того же именованного канала: каждый переносит дескриптор в другой экземпляр именованного канала, обслуживая другого клиента. Именованные экземпляры pipe (даже для одного и того же канала) хранятся отдельно операционной системой, поэтому нет необходимости в каком-либо явном кодировании, чтобы поддерживать связь каждого клиента с сервером отдельно.
То, что вам нужно явно указывать, - это модель потоковой передачи для сервера. Простейший подход к многопоточности сервера объясняется в этом SO-ответе, который включает в себя шаблон псевдокода. Более масштабируемые реализации, если необходимо поддерживать большое количество одновременных вызывающих абонентов, будут использовать пул потоков и асинхронные методы вместо создания выделенного потока для каждого соединения.
Ответ 2
Вы можете написать многопоточный сервер каналов, многократно создавая NamedPipeServerStream и ожидая одного соединения, а затем создавая поток для этого экземпляра NamedPipeServerStream.
У вас может быть только 254 одновременных клиента, но в соответствии с документацией .NET MSDN, приведенной ниже. Для Win32 API, хотя вы можете передать специальное значение, чтобы получить неограниченное количество на основе системных ресурсов. Похоже, что документация MSDN неверна, как указано ниже.
Нижеприведенный код не проверен, поэтому, пожалуйста, не просто копируйте и вставляйте для использования без тестирования:
public class PipeServer
{
bool running;
Thread runningThread;
EventWaitHandle terminateHandle = new EventWaitHandle(false, EventResetMode.AutoReset);
public string PipeName { get; set; }
void ServerLoop()
{
while (running)
{
ProcessNextClient();
}
terminateHandle.Set();
}
public void Run()
{
running = true;
runningThread = new Thread(ServerLoop);
runningThread.Start();
}
public void Stop()
{
running = false;
terminateHandle.WaitOne();
}
public virtual string ProcessRequest(string message)
{
return "";
}
public void ProcessClientThread(object o)
{
NamedPipeServerStream pipeStream = (NamedPipeServerStream)o;
//TODO FOR YOU: Write code for handling pipe client here
pipeStream.Close();
pipeStream.Dispose();
}
public void ProcessNextClient()
{
try
{
NamedPipeServerStream pipeStream = new NamedPipeServerStream(PipeName, PipeDirection.InOut, 254);
pipeStream.WaitForConnection();
//Spawn a new thread for each request and continue waiting
Thread t = new Thread(ProcessClientThread);
t.Start(pipeStream);
}
catch (Exception e)
{//If there are no more avail connections (254 is in use already) then just keep looping until one is avail
}
}
Ответ 3
NamedPipeServerStream - это точка-точка соединения. Вы сами должны сами синхронизировать вызовы - например, вызовы, записанные в очередь, и ваш сервер читает из синхронизированной очереди и выполняет вызовы.