J'ai des problèmes avec les tuyaux nommés. Lorsque, par exemple, 30 clients clusters tentent de se connecter en même temps, à un serveur de canalisation local, sur une machine à 4 cœurs, j'obtiens un timeout ou un timeout de sémaphore. Il faut parfois, pour le plus long temps, une seconde pour qu'un client obtienne la connexion. Puis une seconde de plus pour la suivante et ainsi de suite. Je pensais que l'accès au réseau local était censé être rapide. Pourquoi 30 clients - même 100 clients prendraient le même temps - prendre 1000 millisecondes pour faire une seule connexion?Pourquoi les canaux nommés prennent-ils une longueur inattendue pour se connecter à un serveur de canal local?
using System;
using System.Diagnostics;
using System.IO.Pipes;
using System.Security.AccessControl;
using System.Threading;
using System.Threading.Tasks;
namespace PipeStress
{
class Program
{
public static PipeSecurity CreatePipeSecurity()
{
PipeSecurity ps;
using (var seedPipe = new NamedPipeServerStream("{DDAB520F-5104-48D1-AA65-7AEF568E0045}",
PipeDirection.InOut, 1, PipeTransmissionMode.Message, PipeOptions.None, 1000, 1000))
{
ps = seedPipe.GetAccessControl();
}
var sid = new System.Security.Principal.SecurityIdentifier(
System.Security.Principal.WellKnownSidType.BuiltinUsersSid, null);
ps.AddAccessRule(new PipeAccessRule(sid, PipeAccessRights.ReadWrite |
PipeAccessRights.CreateNewInstance | PipeAccessRights.ChangePermissions,
AccessControlType.Allow));
sid = new System.Security.Principal.SecurityIdentifier(
System.Security.Principal.WellKnownSidType.LocalServiceSid, null);
ps.AddAccessRule(new PipeAccessRule(sid, PipeAccessRights.ReadWrite,
AccessControlType.Allow));
return ps;
}
static void Main(string[] args)
{
Task.Run(() => RunPipeServer());
for (var i = (uint) 0; i < 30; i++)
{
var index = i;
//Thread.Sleep(100);
Task.Run(() => RunPipeClient(index));
}
Console.ReadLine();
}
private const string PipeName = "{6FDABBF8-BFFD-4624-A67B-3211ED7EF0DC}";
static void RunPipeServer()
{
try
{
var stw = new Stopwatch();
while (true)
{
stw.Restart();
var pipeServer = new NamedPipeServerStream(PipeName, PipeDirection.InOut,
NamedPipeServerStream.MaxAllowedServerInstances,
PipeTransmissionMode.Message, PipeOptions.Asynchronous, 4 * 1024, 4 * 1024,
CreatePipeSecurity());
try
{
var pipe = pipeServer;
pipeServer.WaitForConnection();
Console.WriteLine(stw.ElapsedMilliseconds + "ms");
Task.Run(() => HandleClient(pipe));
}
catch (Exception ex)
{
pipeServer.Dispose();
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
private static void HandleClient(NamedPipeServerStream pipeServer)
{
try
{
try
{
//Thread.Sleep(100);
}
finally
{
pipeServer.Close();
}
}
finally
{
pipeServer.Dispose();
}
}
static void RunPipeClient(uint i)
{
try
{
var j = 0;
while (true)
{
using (var pipeClient = new NamedPipeClientStream(".", PipeName, PipeDirection.InOut, PipeOptions.None))
{
//Thread.Sleep(100);
pipeClient.Connect(5000);
try
{
Console.WriteLine($"{i}, {++j}");
pipeClient.ReadByte();
}
finally
{
pipeClient.Close();
}
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
}
}
Merci beaucoup pour la réponse. Cela a été très utile et éclairant. – PieterB