2013-08-26 3 views
7

Le code suivant crée un nouveau thread qui agit d'abord en tant que client de canal nommé pour l'envoi des paramètres, puis en tant que serveur pour la récupération des résultats. Après cela, il exécute une fonction dans un autre AppDomain agissant en tant que serveur de canal nommé et ensuite en tant que client pour renvoyer les résultats.C# toutes les instances de pipeline sont occupées

public OrderPrice DoAction() 
{ 
    Task<OrderPrice> t = Task<OrderPrice>.Factory.StartNew(NamedPipeClient, parameters); 

    if (domain == null) 
    { 
    domain = AppDomain.CreateDomain(DOMAINNAME); 
    } 
    domain.DoCallBack(AppDomainCallback); 

    return t.Result; 
} 

static OrderPrice NamedPipeClient(object parameters) { 
    OrderPrice price = null; 

    using (NamedPipeClientStream stream = new NamedPipeClientStream(PIPE_TO)) { 
    stream.Connect(); 
    SerializeToStream(stream, parameters); 
    } 

    using (NamedPipeServerStream stream = new NamedPipeServerStream(PIPE_BACK)) { 
    stream.WaitForConnection(); 

    price = (OrderPrice)DeserializeFromStream(stream); 
    } 

    return price; 
} 

void AppDomainCallback() { 
    OrderPrice price = null; 

    using (NamedPipeServerStream stream = new NamedPipeServerStream(PIPE_TO)) { 
    stream.WaitForConnection(); 

    List<object> parameters = (List<object>)DeserializeFromStream(stream); 

    if (mi != null) 
     price = (OrderPrice)mi.Invoke(action, parameters.ToArray()); 
} 

    using (NamedPipeClientStream stream = new NamedPipeClientStream(PIPE_BACK)) { 
    stream.Connect(); 
    SerializeToStream(stream, price); 
    } 
} 

Le code est appelé une fois par seconde en moyenne et il a fonctionné correctement pendant 7 heures et plus. Mais à un certain moment "system.io.ioexception toutes les instances de pipe sont occupées" est levée et elles ne se reconnecteront plus après cela. En parcourant ici, il semble que cela puisse être dû au fait que les objets de tuyauterie ne soient pas correctement éliminés, mais je suppose que c'est très bien, car ils utilisent des instructions. Est-ce que quelqu'un a la moindre idée de ce qui pourrait être mauvais ici? Le code est en cours d'exécution .NET 4.0 sur Windows Server 2008.

+3

L'exception est levée lorsque vous essayez d'accéder à un tuyau à partir de plusieurs threads à la fois. Les tuyaux ne sont pas adaptés aux threads, êtes-vous sûr de ne pas y accéder simultanément avec les deux threads? – hcb

+0

lors de la création de plusieurs threads qui appellent DoAction, le code se bloque lors du premier appel car une seconde instance NamedPipeServerStream (PIPE_TO) est créée. J'ai essayé d'ajouter un verrou (SyncToObject) mais le code est entré deux fois encore. Je pense que parce qu'il s'exécute dans un AppDomain distinct, mais je ne sais pas comment utiliser les objets dans des Appdomains distincts – Laurijssen

+0

Pouvez-vous déplacer l'appel à AppDomainCallback() dans la tâche? Ou est-ce que cette méthode est appelée automatiquement sur un autre thread parce que c'est dans un autre domaine? – hcb

Répondre

Questions connexes